<commit_before>const fs = require('fs');
const passport = require('passport');
const JWTStrategy = require('passport-jwt').Strategy;
const extractors = require('./extractors');
const services = require('../../services');

module.exports = function (params) {
  const secretOrKey = params.secretOrPubKeyFile ? fs.readFileSync(params.secretOrPubKeyFile) : params.secretOrPubKey;
  const extractor = extractors[params.jwtExtractor](params.jwtExtractorField);

  passport.use(new JWTStrategy({
    secretOrKey,
    jwtFromRequest: extractor,
    audience: params.audience,
    issuer: params.issuer
  }, (jwtPayload, done) => {
    if (!jwtPayload) {
      return done(null, false);
    }

    if (!params.checkCredentialExistence) {
      return done(null, { id: 'anonymous' });
    }

    if (!jwtPayload.sub) {
      return done(null, false);
    }

    services.credential.getCredential(jwtPayload.sub, 'jwt')
      .then(credential => {
        if (!credential || !credential.isActive) {
          return false;
        }
        return credential.consumerId;
      })
      .then(services.auth.validateConsumer)
      .then((consumer) => {
        if (!consumer) {
          return done(null, false);
        }

        return done(null, consumer);
      }).catch(done);
  }));

  return function (req, res, next) {
    params.session = false;
    passport.authenticate('jwt', params, params.getCommonAuthCallback(req, res, next))(req, res, next);
  };
};
<commit_msg>Call the callback if the credential isn't found.<commit_after>const fs = require('fs');
const passport = require('passport');
const JWTStrategy = require('passport-jwt').Strategy;
const extractors = require('./extractors');
const services = require('../../services');

module.exports = function (params) {
  const secretOrKey = params.secretOrPubKeyFile ? fs.readFileSync(params.secretOrPubKeyFile) : params.secretOrPubKey;
  const extractor = extractors[params.jwtExtractor](params.jwtExtractorField);

  passport.use(new JWTStrategy({
    secretOrKey,
    jwtFromRequest: extractor,
    audience: params.audience,
    issuer: params.issuer
  }, (jwtPayload, done) => {
    if (!jwtPayload) {
      return done(null, false);
    }

    if (!params.checkCredentialExistence) {
      return done(null, { id: 'anonymous' });
    }

    if (!jwtPayload.sub) {
      return done(null, false);
    }

    services.credential.getCredential(jwtPayload.sub, 'jwt')
      .then(credential => {
        if (!credential || !credential.isActive) {
          return done(null, false);
        }
        return credential.consumerId;
      })
      .then(services.auth.validateConsumer)
      .then((consumer) => {
        if (!consumer) {
          return done(null, false);
        }

        return done(null, consumer);
      }).catch(done);
  }));

  return function (req, res, next) {
    params.session = false;
    passport.authenticate('jwt', params, params.getCommonAuthCallback(req, res, next))(req, res, next);
  };
};
<|endoftext|>


<commit_before>module.exports = function(grunt) {
    grunt.loadNpmTasks('grunt-contrib-symlink');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-coffee');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-commands');

    var filesLess = {},
        filesCoffee = {};

    // Configuration
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        symlink: {
            fontawesome_font_otf: {
                src: 'bower_components/font-awesome/fonts/FontAwesome.otf',
                dest: 'web/fonts/FontAwesome.otf'
            },
            fontawesome_font_eot: {
                src: 'bower_components/font-awesome/fonts/fontawesome-webfont.eot',
                dest: 'web/fonts/fontawesome-webfont.eot'
            },
            fontawesome_font_svg: {
                src: 'bower_components/font-awesome/fonts/fontawesome-webfont.svg',
                dest: 'web/fonts/fontawesome-webfont.svg'
            },
            fontawesome_font_ttf: {
                src: 'bower_components/font-awesome/fonts/fontawesome-webfont.ttf',
                dest: 'web/fonts/fontawesome-webfont.ttf'
            },
            fontawesome_font_woff: {
                src: 'bower_components/font-awesome/fonts/fontawesome-webfont.woff',
                dest: 'web/fonts/fontawesome-webfont.woff'
            },
            bootstrap_font_eot: {
                src: 'bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.eot',
                dest: 'web/fonts/glyphicons-halflings-regular.eot'
            },
            bootstrap_font_svg: {
                src: 'bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.svg',
                dest: 'web/fonts/glyphicons-halflings-regular.svg'
            },
            bootstrap_font_ttf: {
                src: 'bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf',
                dest: 'web/fonts/glyphicons-halflings-regular.ttf'
            },
            bootstrap_font_woff: {
                src: 'bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff',
                dest: 'web/fonts/glyphicons-halflings-regular.woff'
            },
            datatable_img_sort_asc: {
                src: 'bower_components/datatables/media/images/sort_asc.png',
                dest: 'web/images/sort_asc.png'
            },
            datatable_img_sort_both: {
                src: 'bower_components/datatables/media/images/sort_both.png',
                dest: 'web/images/sort_both.png'
            },
            datatable_img_sort_desc: {
                src: 'bower_components/datatables/media/images/sort_desc.png',
                dest: 'web/images/sort_desc.png'
            },
            smartadmin_bg: {
                src: 'web/bundles/phporchestracms/img/mybg.png',
                dest: 'web/img/mybg.png'
            }
        },

        clean: {
            built: ["web/built"]
        },

        less: {
            bundles: {
                files: filesLess
            }
        },

        cssmin: {
            minify: {
                expand: true,
                src: ['web/built/all.css'],
                ext: '.min.css'
            }
        },

        coffee: {
            compileBare: {
                options: {
                    bare: true
                },
                files: filesCoffee
            }
        },

        uglify: {
            dist: {
                files: {
                    'web/built/all.min.js': ['web/built/all.js'],
                    'web/built/translation.min.js': ['web/built/translation.js']
                }
            }
        },

        concat: {
            bowerjs: {
                src: [
                    'bower_components/jquery/jquery.js',
                    'bower_components/jquery-ui/ui/jquery-ui.js',
                    'bower_components/bootstrap/dist/js/bootstrap.js',
                    'bower_components/underscore/underscore.js',
                    'bower_components/backbone/backbone.js',
                    'bower_components/datatables/media/js/jquery.dataTables.js',
                    'bower_components/jquery.easypiechart.js/dist/jquery.easypiechart.js',
                    'bower_components/fancytree/dist/jquery.fancytree.js',
                    'bower_components/jquery-form/jquery.form.js'
                ],
                dest: 'web/built/bower.js'
            },
            translationjs: {
                src: [
                    'bower_components/jquery/jquery.js',
                    'bower_components/angular/angular.js',
                    'web/bundles/lexiktranslation/ng-table/ng-table.min.js'
                ],
                dest: 'web/built/translation.js'
            },
            js: {
                src: [
                    // BOWER
                    'web/built/bower.js',

                    // PHPORCHESTRACMS
                    'web/bundles/phporchestracms/js/confirmDialog.js',
                    'web/bundles/phporchestracms/js/phporchestra.js',
                    'web/bundles/phporchestrabackoffice/smartadmin/notification/SmartNotification.js',
                    'web/bundles/phporchestrabackoffice/smartadmin/smartwigdets/jarvis.widget.js',
                    'web/bundles/phporchestracms/js/app0.js',

                    // PHPORCHESTRAINDEXATION
                    'web/bundles/phporchestraindexation/js/*.js',

                    // STFALCONTINYMCE
                    'web/bundles/stfalcontinymce/js/*.js',
                    'web/bundles/stfalcontinymce/vendor/tinymce/*.js',

                    // COFFEE
                    'web/built/*/js/*.js',
                    'web/built/*/js/*/*.js'
                    ],
                dest: 'web/built/all.js'
            },
            bowercss: {
                src: [
                    'bower_components/bootstrap/dist/css/bootstrap.css',
                    'bower_components/jquery-ui/themes/base/jquery-ui.css',
                    'bower_components/font-awesome/css/font-awesome.css',
                    'bower_components/datatables/media/css/jquery.dataTables.css',
                    'bower_components/fancytree/dist/skin-bootstrap/ui.fancytree.css'
                ],
                dest: 'web/built/bower.css'
            },
            css: {
                src: [
                    'web/built/bower.css',
                    //'web/built/*/css/**.css',
                    'web/bundles/phporchestrabackoffice/smartadmin/smartadmin-production.css',
                    'web/bundles/phporchestrabackoffice/smartadmin/smartadmin-skins.css',
                    'web/built/phporchestracms/css/ribbon.css',
                    'web/built/phporchestracms/css/phpfactory.css',
                    'web/built/phporchestracms/css/template.css',
                    'web/bundles/lexiktranslation/ng-table/ng-table.min.css',
                ],
                dest: 'web/built/all.css'
            }
        },

        watch: {
            css: {
                files: ['web/bundles/*/less/*.less'],
                tasks: ['css', 'command:assetic_dump']
            },
            javascript: {
                files: ['web/bundles/*/coffee/*.coffee'],
                tasks: ['javascript', 'command:assetic_dump']
            }
        },

        command : {
            assets_install: {
                cmd  : 'php app/console assets:install --symlink'
            },
            assetic_dump: {
                cmd  : 'php app/console assetic:dump'
            }
        }
    });

    // Default task(s).
    grunt.registerTask('default', ['clean', 'command:assets_install', 'symlink', 'concat:bowercss', 'css', 'concat:bowerjs', 'javascript', 'javascriptProd', 'command:assetic_dump']);
    grunt.registerTask('css', ['less:discovering', 'less', 'concat:css', 'cssmin']);
    grunt.registerTask('javascript', ['coffee:discovering', 'coffee', 'concat:js', 'concat:translationjs']);
    grunt.registerTask('javascriptProd', ['uglify']);
    grunt.registerTask('less:discovering', 'This is a function', function() {
        // LESS Files management
        // Source LESS files are located inside : bundles/[bundle]/less/
        // Destination CSS files are located inside : built/[bundle]/css/
        var mappingFileLess = grunt.file.expandMapping(
            ['*/less/*.less', '*/less/*/*.less'],
            'web/built/', {
                cwd: 'web/bundles/',
                rename: function(dest, matchedSrcPath, options) {
                    return dest + matchedSrcPath.replace(/less/g, 'css');
                }
            });

        grunt.util._.each(mappingFileLess, function(value) {
            // Why value.src is an array ??
            filesLess[value.dest] = value.src[0];
        });
    });
    grunt.registerTask('coffee:discovering', 'This is a function', function() {
        // COFFEE Files management
        // Source COFFEE files are located inside : bundles/[bundle]/coffee/
        // Destination JS files are located inside : built/[bundle]/js/
        var mappingFileCoffee = grunt.file.expandMapping(
            ['*/coffee/*.coffee', '*/coffee/*/*.coffee'],
            'web/built/', {
                cwd: 'web/bundles/',
                rename: function(dest, matchedSrcPath, options) {
                    return dest + matchedSrcPath.replace(/coffee/g, 'js');
                }
            });

        grunt.util._.each(mappingFileCoffee, function(value) {
            // Why value.src is an array ??
            filesCoffee[value.dest] = value.src[0];
        });
    });
};
<commit_msg>Remove tranlationjs task (introduced a jquery env override)<commit_after>module.exports = function(grunt) {
    grunt.loadNpmTasks('grunt-contrib-symlink');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-coffee');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-commands');

    var filesLess = {},
        filesCoffee = {};

    // Configuration
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        symlink: {
            fontawesome_font_otf: {
                src: 'bower_components/font-awesome/fonts/FontAwesome.otf',
                dest: 'web/fonts/FontAwesome.otf'
            },
            fontawesome_font_eot: {
                src: 'bower_components/font-awesome/fonts/fontawesome-webfont.eot',
                dest: 'web/fonts/fontawesome-webfont.eot'
            },
            fontawesome_font_svg: {
                src: 'bower_components/font-awesome/fonts/fontawesome-webfont.svg',
                dest: 'web/fonts/fontawesome-webfont.svg'
            },
            fontawesome_font_ttf: {
                src: 'bower_components/font-awesome/fonts/fontawesome-webfont.ttf',
                dest: 'web/fonts/fontawesome-webfont.ttf'
            },
            fontawesome_font_woff: {
                src: 'bower_components/font-awesome/fonts/fontawesome-webfont.woff',
                dest: 'web/fonts/fontawesome-webfont.woff'
            },
            bootstrap_font_eot: {
                src: 'bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.eot',
                dest: 'web/fonts/glyphicons-halflings-regular.eot'
            },
            bootstrap_font_svg: {
                src: 'bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.svg',
                dest: 'web/fonts/glyphicons-halflings-regular.svg'
            },
            bootstrap_font_ttf: {
                src: 'bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf',
                dest: 'web/fonts/glyphicons-halflings-regular.ttf'
            },
            bootstrap_font_woff: {
                src: 'bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff',
                dest: 'web/fonts/glyphicons-halflings-regular.woff'
            },
            datatable_img_sort_asc: {
                src: 'bower_components/datatables/media/images/sort_asc.png',
                dest: 'web/images/sort_asc.png'
            },
            datatable_img_sort_both: {
                src: 'bower_components/datatables/media/images/sort_both.png',
                dest: 'web/images/sort_both.png'
            },
            datatable_img_sort_desc: {
                src: 'bower_components/datatables/media/images/sort_desc.png',
                dest: 'web/images/sort_desc.png'
            },
            smartadmin_bg: {
                src: 'web/bundles/phporchestracms/img/mybg.png',
                dest: 'web/img/mybg.png'
            }
        },

        clean: {
            built: ["web/built"]
        },

        less: {
            bundles: {
                files: filesLess
            }
        },

        cssmin: {
            minify: {
                expand: true,
                src: ['web/built/all.css'],
                ext: '.min.css'
            }
        },

        coffee: {
            compileBare: {
                options: {
                    bare: true
                },
                files: filesCoffee
            }
        },

        uglify: {
            dist: {
                files: {
                    'web/built/all.min.js': ['web/built/all.js'],
                    'web/built/translation.min.js': ['web/built/translation.js']
                }
            }
        },

        concat: {
            bowerjs: {
                src: [
                    'bower_components/jquery/jquery.js',
                    'bower_components/jquery-ui/ui/jquery-ui.js',
                    'bower_components/bootstrap/dist/js/bootstrap.js',
                    'bower_components/underscore/underscore.js',
                    'bower_components/backbone/backbone.js',
                    'bower_components/angular/angular.js',
                    'bower_components/datatables/media/js/jquery.dataTables.js',
                    'bower_components/jquery.easypiechart.js/dist/jquery.easypiechart.js',
                    'bower_components/fancytree/dist/jquery.fancytree.js',
                    'bower_components/jquery-form/jquery.form.js'
                ],
                dest: 'web/built/bower.js'
            },
            js: {
                src: [
                    // BOWER
                    'web/built/bower.js',

                    // PHPORCHESTRACMS
                    'web/bundles/phporchestracms/js/confirmDialog.js',
                    'web/bundles/phporchestracms/js/phporchestra.js',
                    'web/bundles/phporchestrabackoffice/smartadmin/notification/SmartNotification.js',
                    'web/bundles/phporchestrabackoffice/smartadmin/smartwigdets/jarvis.widget.js',
                    'web/bundles/phporchestracms/js/app0.js',

                    // PHPORCHESTRAINDEXATION
                    'web/bundles/phporchestraindexation/js/*.js',

                    // STFALCONTINYMCE
                    'web/bundles/stfalcontinymce/js/*.js',
                    'web/bundles/stfalcontinymce/vendor/tinymce/*.js',

                    // COFFEE
                    'web/built/*/js/*.js',
                    'web/built/*/js/*/*.js',

                    // LEXIKTRANSLATION
                    'web/bundles/lexiktranslation/ng-table/ng-table.min.js'
                ],
                dest: 'web/built/all.js'
            },
            bowercss: {
                src: [
                    'bower_components/bootstrap/dist/css/bootstrap.css',
                    'bower_components/jquery-ui/themes/base/jquery-ui.css',
                    'bower_components/font-awesome/css/font-awesome.css',
                    'bower_components/datatables/media/css/jquery.dataTables.css',
                    'bower_components/fancytree/dist/skin-bootstrap/ui.fancytree.css'
                ],
                dest: 'web/built/bower.css'
            },
            css: {
                src: [
                    'web/built/bower.css',
                    //'web/built/*/css/**.css',
                    'web/bundles/phporchestrabackoffice/smartadmin/smartadmin-production.css',
                    'web/bundles/phporchestrabackoffice/smartadmin/smartadmin-skins.css',
                    'web/built/phporchestracms/css/ribbon.css',
                    'web/built/phporchestracms/css/phpfactory.css',
                    'web/built/phporchestracms/css/template.css',
                    'web/bundles/lexiktranslation/ng-table/ng-table.min.css',
                ],
                dest: 'web/built/all.css'
            }
        },

        watch: {
            css: {
                files: ['web/bundles/*/less/*.less'],
                tasks: ['css', 'command:assetic_dump']
            },
            javascript: {
                files: ['web/bundles/*/coffee/*.coffee'],
                tasks: ['javascript', 'command:assetic_dump']
            }
        },

        command : {
            assets_install: {
                cmd  : 'php app/console assets:install --symlink'
            },
            assetic_dump: {
                cmd  : 'php app/console assetic:dump'
            }
        }
    });

    // Default task(s).
    grunt.registerTask('default', ['clean', 'command:assets_install', 'symlink', 'concat:bowercss', 'css', 'concat:bowerjs', 'javascript', 'javascriptProd', 'command:assetic_dump']);
    grunt.registerTask('css', ['less:discovering', 'less', 'concat:css', 'cssmin']);
    grunt.registerTask('javascript', ['coffee:discovering', 'coffee', 'concat:js']);
    grunt.registerTask('javascriptProd', ['uglify']);
    grunt.registerTask('less:discovering', 'This is a function', function() {
        // LESS Files management
        // Source LESS files are located inside : bundles/[bundle]/less/
        // Destination CSS files are located inside : built/[bundle]/css/
        var mappingFileLess = grunt.file.expandMapping(
            ['*/less/*.less', '*/less/*/*.less'],
            'web/built/', {
                cwd: 'web/bundles/',
                rename: function(dest, matchedSrcPath, options) {
                    return dest + matchedSrcPath.replace(/less/g, 'css');
                }
            });

        grunt.util._.each(mappingFileLess, function(value) {
            // Why value.src is an array ??
            filesLess[value.dest] = value.src[0];
        });
    });
    grunt.registerTask('coffee:discovering', 'This is a function', function() {
        // COFFEE Files management
        // Source COFFEE files are located inside : bundles/[bundle]/coffee/
        // Destination JS files are located inside : built/[bundle]/js/
        var mappingFileCoffee = grunt.file.expandMapping(
            ['*/coffee/*.coffee', '*/coffee/*/*.coffee'],
            'web/built/', {
                cwd: 'web/bundles/',
                rename: function(dest, matchedSrcPath, options) {
                    return dest + matchedSrcPath.replace(/coffee/g, 'js');
                }
            });

        grunt.util._.each(mappingFileCoffee, function(value) {
            // Why value.src is an array ??
            filesCoffee[value.dest] = value.src[0];
        });
    });
};
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2015 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

goog.provide('shaka.polyfill.Promise');

goog.require('shaka.asserts');
goog.require('shaka.log');

/**
 * @namespace shaka.polyfill.Promise
 * @exportDoc
 *
 * @summary A polyfill to implement Promises, primarily for IE.
 * Does not support thenables, but otherwise passes the A+ conformance tests.
 * Note that Promise.all() and Promise.race() are not tested by that suite.
 */

/**
 * @constructor
 * @param {function(function(*), function(*))=} opt_callback
 */
shaka.polyfill.Promise = function(opt_callback) {
  /** @private {!Array.<shaka.polyfill.Promise.Child>} */
  this.thens_ = [];

  /** @private {!Array.<shaka.polyfill.Promise.Child>} */
  this.catches_ = [];

  /** @private {shaka.polyfill.Promise.State} */
  this.state_ = shaka.polyfill.Promise.State.PENDING;

  /** @private {*} */
  this.value_;

  // External callers must supply the callback.  Internally, we may construct
  // child Promises without it, since we can directly access their resolve_ and
  // reject_ methods when convenient.
  if (opt_callback) {
    try {
      opt_callback(this.resolve_.bind(this), this.reject_.bind(this));
    } catch (e) {
      this.reject_(e);
    }
  }
};

/**
 * @typedef {{
 *   promise: !shaka.polyfill.Promise,
 *   callback: (function(*)|undefined)
 * }}
 */
shaka.polyfill.Promise.Child;

/**
 * @enum {number}
 */
shaka.polyfill.Promise.State = {
  PENDING: 0,
  RESOLVED: 1,
  REJECTED: 2
};

/**
 * Install the polyfill if needed.
 * @export
 */
shaka.polyfill.Promise.install = function() {
  if (window.Promise) {
    shaka.log.info('Using native Promises.');
    return;
  }

  shaka.log.info('Using Promises polyfill.');
  window['Promise'] = shaka.polyfill.Promise;

  // Decide on the best way to invoke a callback as soon as possible.
  // Precompute the Promise.soon_ convenience method to avoid the overhead
  // of this switch every time a callback has to be invoked.
  if (window.setImmediate) {
    // For IE and node.js:
    shaka.polyfill.Promise.soon_ = function(callback) {
      window.setImmediate(callback);
    };
  } else {
    shaka.polyfill.Promise.soon_ = function(callback) {
      window.setTimeout(callback, 0);
    };
  }
};

/**
 * @param {*} value
 * @return {!shaka.polyfill.Promise}
 */
shaka.polyfill.Promise.resolve = function(value) {
  var p = new shaka.polyfill.Promise();
  p.resolve_(value);
  return p;
};

/**
 * @param {*} reason
 * @return {!shaka.polyfill.Promise}
 */
shaka.polyfill.Promise.reject = function(reason) {
  var p = new shaka.polyfill.Promise();
  p.reject_(reason);
  return p;
};

/**
 * @param {!Array.<!shaka.polyfill.Promise>} others
 * @return {!shaka.polyfill.Promise}
 */
shaka.polyfill.Promise.all = function(others) {
  var p = new shaka.polyfill.Promise();
  if (!others.length) {
    p.resolve_([]);
    return p;
  }

  // The array of results must be in the same order as the array of Promises
  // passed to all().  So we pre-allocate the array and keep a count of how
  // many have resolved.  Only when all have resolved is the returned Promise
  // itself resolved.
  var count = 0;
  var values = new Array(others.length);
  var resolve = function(p, i, newValue) {
    shaka.asserts.assert(p.state_ != shaka.polyfill.Promise.State.RESOLVED);
    // If one of the Promises in the array was rejected, this Promise was
    // rejected and new values are ignored.  In such a case, the values array
    // and its contents continue to be alive in memory until all of the Promises
    // in the array have completed.
    if (p.state_ == shaka.polyfill.Promise.State.PENDING) {
      values[i] = newValue;
      count++;
      if (count == values.length) {
        p.resolve_(values);
      }
    }
  };

  var reject = p.reject_.bind(p);
  for (var i = 0; i < others.length; ++i) {
    if (others[i].then) {
      others[i].then(resolve.bind(null, p, i), reject);
    } else {
      resolve(p, i, others[i]);
    }
  }
  return p;
};

/**
 * @param {!Array.<!shaka.polyfill.Promise>} others
 * @return {!shaka.polyfill.Promise}
 */
shaka.polyfill.Promise.race = function(others) {
  var p = new shaka.polyfill.Promise();

  // The returned Promise is resolved or rejected as soon as one of the others
  // is.
  var resolve = p.resolve_.bind(p);
  var reject = p.reject_.bind(p);
  for (var i = 0; i < others.length; ++i) {
    if (others[i].then) {
      others[i].then(resolve, reject);
    } else {
      resolve(others[i]);
    }
  }
  return p;
};

/**
 * @param {function(*)=} opt_successCallback
 * @param {function(*)=} opt_failCallback
 * @return {!shaka.polyfill.Promise}
 * @export
 */
shaka.polyfill.Promise.prototype.then = function(opt_successCallback,
                                                 opt_failCallback) {
  // then() returns a child Promise which is chained onto this one.
  var child = new shaka.polyfill.Promise();
  switch (this.state_) {
    case shaka.polyfill.Promise.State.RESOLVED:
      // This is already resolved, so we can chain to the child ASAP.
      this.schedule_(child, opt_successCallback);
      break;
    case shaka.polyfill.Promise.State.REJECTED:
      // This is already rejected, so we can chain to the child ASAP.
      this.schedule_(child, opt_failCallback);
      break;
    case shaka.polyfill.Promise.State.PENDING:
      // This is pending, so we have to track both callbacks and the child
      // in order to chain later.
      this.thens_.push({ promise: child, callback: opt_successCallback});
      this.catches_.push({ promise: child, callback: opt_failCallback});
      break;
  }

  return child;
};

/**
 * @param {function(*)} callback
 * @return {!shaka.polyfill.Promise}
 * @export
 */
shaka.polyfill.Promise.prototype.catch = function(callback) {
  // Devolves into a two-argument call to 'then'.
  return this.then(undefined, callback);
};

/**
 * @param {*} value
 * @private
 */
shaka.polyfill.Promise.prototype.resolve_ = function(value) {
  // Ignore resolve calls if we aren't still pending.
  if (this.state_ == shaka.polyfill.Promise.State.PENDING) {
    this.value_ = value;
    this.state_ = shaka.polyfill.Promise.State.RESOLVED;
    // Schedule calls to all of the chained callbacks.
    for (var i = 0; i < this.thens_.length; ++i) {
      this.schedule_(this.thens_[i].promise, this.thens_[i].callback);
    }
    this.thens_ = [];
    this.catches_ = [];
  }
};

/**
 * @param {*} reason
 * @private
 */
shaka.polyfill.Promise.prototype.reject_ = function(reason) {
  // Ignore reject calls if we aren't still pending.
  if (this.state_ == shaka.polyfill.Promise.State.PENDING) {
    this.value_ = reason;
    this.state_ = shaka.polyfill.Promise.State.REJECTED;
    // Schedule calls to all of the chained callbacks.
    for (var i = 0; i < this.catches_.length; ++i) {
      this.schedule_(this.catches_[i].promise, this.catches_[i].callback);
    }
    this.thens_ = [];
    this.catches_ = [];
  }
};

/**
 * @param {!shaka.polyfill.Promise} child
 * @param {function(*)|undefined} callback
 * @private
 */
shaka.polyfill.Promise.prototype.schedule_ = function(child, callback) {
  shaka.asserts.assert(this.state_ != shaka.polyfill.Promise.State.PENDING);

  var wrapper = function() {
    if (callback && typeof callback == 'function') {
      // Wrap around the callback.  Exceptions thrown by the callback are
      // converted to failures.
      try {
        var value = callback(this.value_);
      } catch (exception) {
        child.reject_(exception);
        return;
      }

      if (value instanceof shaka.polyfill.Promise) {
        // If the returned value is a Promise, we bind it's state to the child.
        if (value == child) {
          // Without this, a bad calling pattern can cause an infinite loop.
          child.reject_(new TypeError('Chaining cycle detected'));
        } else {
          value.then(child.resolve_.bind(child), child.reject_.bind(child));
        }
      } else {
        // If the returned value is not a Promise, the child is resolved with
        // that value.
        child.resolve_(value);
      }
    } else if (this.state_ == shaka.polyfill.Promise.State.RESOLVED) {
      // No callback for this state, so just chain on down the line.
      child.resolve_(this.value_);
    } else {
      // No callback for this state, so just chain on down the line.
      child.reject_(this.value_);
    }
  };

  // Call the wrapper ASAP.
  shaka.polyfill.Promise.soon_(wrapper.bind(this));
};

/**
 * @param {function()} callback
 * Schedule a callback as soon as possible.
 * Bound in shaka.polyfill.Promise.install() to a specific implementation.
 * @private
 */
shaka.polyfill.Promise.soon_ = function(callback) {};
<commit_msg>Fix compiled Promise polyfill<commit_after>/**
 * @license
 * Copyright 2015 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

goog.provide('shaka.polyfill.Promise');

goog.require('shaka.asserts');
goog.require('shaka.log');

/**
 * @namespace shaka.polyfill.Promise
 * @exportDoc
 *
 * @summary A polyfill to implement Promises, primarily for IE.
 * Does not support thenables, but otherwise passes the A+ conformance tests.
 * Note that Promise.all() and Promise.race() are not tested by that suite.
 */

/**
 * @constructor
 * @param {function(function(*), function(*))=} opt_callback
 */
shaka.polyfill.Promise = function(opt_callback) {
  /** @private {!Array.<shaka.polyfill.Promise.Child>} */
  this.thens_ = [];

  /** @private {!Array.<shaka.polyfill.Promise.Child>} */
  this.catches_ = [];

  /** @private {shaka.polyfill.Promise.State} */
  this.state_ = shaka.polyfill.Promise.State.PENDING;

  /** @private {*} */
  this.value_;

  // External callers must supply the callback.  Internally, we may construct
  // child Promises without it, since we can directly access their resolve_ and
  // reject_ methods when convenient.
  if (opt_callback) {
    try {
      opt_callback(this.resolve_.bind(this), this.reject_.bind(this));
    } catch (e) {
      this.reject_(e);
    }
  }
};

/**
 * @typedef {{
 *   promise: !shaka.polyfill.Promise,
 *   callback: (function(*)|undefined)
 * }}
 */
shaka.polyfill.Promise.Child;

/**
 * @enum {number}
 */
shaka.polyfill.Promise.State = {
  PENDING: 0,
  RESOLVED: 1,
  REJECTED: 2
};

/**
 * Install the polyfill if needed.
 * @export
 */
shaka.polyfill.Promise.install = function() {
  if (window.Promise) {
    shaka.log.info('Using native Promises.');
    return;
  }

  shaka.log.info('Using Promises polyfill.');
  // Quoted to work around type-checking, since our then() signature doesn't
  // exactly match that of a native Promise.
  window['Promise'] = shaka.polyfill.Promise;

  // Explicitly installed because the compiler won't necessarily attach them
  // to the compiled constructor.  Exporting them will only attach them to
  // their original namespace, which isn't the same as attaching them to the
  // constructor unless you also export the constructor.
  window.Promise.resolve = shaka.polyfill.Promise.resolve;
  window.Promise.reject = shaka.polyfill.Promise.reject;
  window.Promise.all = shaka.polyfill.Promise.all;
  window.Promise.race = shaka.polyfill.Promise.race;

  // Decide on the best way to invoke a callback as soon as possible.
  // Precompute the Promise.soon_ convenience method to avoid the overhead
  // of this switch every time a callback has to be invoked.
  if (window.setImmediate) {
    // For IE and node.js:
    shaka.polyfill.Promise.soon_ = function(callback) {
      window.setImmediate(callback);
    };
  } else {
    shaka.polyfill.Promise.soon_ = function(callback) {
      window.setTimeout(callback, 0);
    };
  }
};

/**
 * @param {*} value
 * @return {!shaka.polyfill.Promise}
 */
shaka.polyfill.Promise.resolve = function(value) {
  var p = new shaka.polyfill.Promise();
  p.resolve_(value);
  return p;
};

/**
 * @param {*} reason
 * @return {!shaka.polyfill.Promise}
 */
shaka.polyfill.Promise.reject = function(reason) {
  var p = new shaka.polyfill.Promise();
  p.reject_(reason);
  return p;
};

/**
 * @param {!Array.<!shaka.polyfill.Promise>} others
 * @return {!shaka.polyfill.Promise}
 */
shaka.polyfill.Promise.all = function(others) {
  var p = new shaka.polyfill.Promise();
  if (!others.length) {
    p.resolve_([]);
    return p;
  }

  // The array of results must be in the same order as the array of Promises
  // passed to all().  So we pre-allocate the array and keep a count of how
  // many have resolved.  Only when all have resolved is the returned Promise
  // itself resolved.
  var count = 0;
  var values = new Array(others.length);
  var resolve = function(p, i, newValue) {
    shaka.asserts.assert(p.state_ != shaka.polyfill.Promise.State.RESOLVED);
    // If one of the Promises in the array was rejected, this Promise was
    // rejected and new values are ignored.  In such a case, the values array
    // and its contents continue to be alive in memory until all of the Promises
    // in the array have completed.
    if (p.state_ == shaka.polyfill.Promise.State.PENDING) {
      values[i] = newValue;
      count++;
      if (count == values.length) {
        p.resolve_(values);
      }
    }
  };

  var reject = p.reject_.bind(p);
  for (var i = 0; i < others.length; ++i) {
    if (others[i].then) {
      others[i].then(resolve.bind(null, p, i), reject);
    } else {
      resolve(p, i, others[i]);
    }
  }
  return p;
};

/**
 * @param {!Array.<!shaka.polyfill.Promise>} others
 * @return {!shaka.polyfill.Promise}
 */
shaka.polyfill.Promise.race = function(others) {
  var p = new shaka.polyfill.Promise();

  // The returned Promise is resolved or rejected as soon as one of the others
  // is.
  var resolve = p.resolve_.bind(p);
  var reject = p.reject_.bind(p);
  for (var i = 0; i < others.length; ++i) {
    if (others[i].then) {
      others[i].then(resolve, reject);
    } else {
      resolve(others[i]);
    }
  }
  return p;
};

/**
 * @param {function(*)=} opt_successCallback
 * @param {function(*)=} opt_failCallback
 * @return {!shaka.polyfill.Promise}
 * @export
 */
shaka.polyfill.Promise.prototype.then = function(opt_successCallback,
                                                 opt_failCallback) {
  // then() returns a child Promise which is chained onto this one.
  var child = new shaka.polyfill.Promise();
  switch (this.state_) {
    case shaka.polyfill.Promise.State.RESOLVED:
      // This is already resolved, so we can chain to the child ASAP.
      this.schedule_(child, opt_successCallback);
      break;
    case shaka.polyfill.Promise.State.REJECTED:
      // This is already rejected, so we can chain to the child ASAP.
      this.schedule_(child, opt_failCallback);
      break;
    case shaka.polyfill.Promise.State.PENDING:
      // This is pending, so we have to track both callbacks and the child
      // in order to chain later.
      this.thens_.push({ promise: child, callback: opt_successCallback});
      this.catches_.push({ promise: child, callback: opt_failCallback});
      break;
  }

  return child;
};

/**
 * @param {function(*)} callback
 * @return {!shaka.polyfill.Promise}
 * @export
 */
shaka.polyfill.Promise.prototype.catch = function(callback) {
  // Devolves into a two-argument call to 'then'.
  return this.then(undefined, callback);
};

/**
 * @param {*} value
 * @private
 */
shaka.polyfill.Promise.prototype.resolve_ = function(value) {
  // Ignore resolve calls if we aren't still pending.
  if (this.state_ == shaka.polyfill.Promise.State.PENDING) {
    this.value_ = value;
    this.state_ = shaka.polyfill.Promise.State.RESOLVED;
    // Schedule calls to all of the chained callbacks.
    for (var i = 0; i < this.thens_.length; ++i) {
      this.schedule_(this.thens_[i].promise, this.thens_[i].callback);
    }
    this.thens_ = [];
    this.catches_ = [];
  }
};

/**
 * @param {*} reason
 * @private
 */
shaka.polyfill.Promise.prototype.reject_ = function(reason) {
  // Ignore reject calls if we aren't still pending.
  if (this.state_ == shaka.polyfill.Promise.State.PENDING) {
    this.value_ = reason;
    this.state_ = shaka.polyfill.Promise.State.REJECTED;
    // Schedule calls to all of the chained callbacks.
    for (var i = 0; i < this.catches_.length; ++i) {
      this.schedule_(this.catches_[i].promise, this.catches_[i].callback);
    }
    this.thens_ = [];
    this.catches_ = [];
  }
};

/**
 * @param {!shaka.polyfill.Promise} child
 * @param {function(*)|undefined} callback
 * @private
 */
shaka.polyfill.Promise.prototype.schedule_ = function(child, callback) {
  shaka.asserts.assert(this.state_ != shaka.polyfill.Promise.State.PENDING);

  var wrapper = function() {
    if (callback && typeof callback == 'function') {
      // Wrap around the callback.  Exceptions thrown by the callback are
      // converted to failures.
      try {
        var value = callback(this.value_);
      } catch (exception) {
        child.reject_(exception);
        return;
      }

      if (value instanceof shaka.polyfill.Promise) {
        // If the returned value is a Promise, we bind it's state to the child.
        if (value == child) {
          // Without this, a bad calling pattern can cause an infinite loop.
          child.reject_(new TypeError('Chaining cycle detected'));
        } else {
          value.then(child.resolve_.bind(child), child.reject_.bind(child));
        }
      } else {
        // If the returned value is not a Promise, the child is resolved with
        // that value.
        child.resolve_(value);
      }
    } else if (this.state_ == shaka.polyfill.Promise.State.RESOLVED) {
      // No callback for this state, so just chain on down the line.
      child.resolve_(this.value_);
    } else {
      // No callback for this state, so just chain on down the line.
      child.reject_(this.value_);
    }
  };

  // Call the wrapper ASAP.
  shaka.polyfill.Promise.soon_(wrapper.bind(this));
};

/**
 * @param {function()} callback
 * Schedule a callback as soon as possible.
 * Bound in shaka.polyfill.Promise.install() to a specific implementation.
 * @private
 */
shaka.polyfill.Promise.soon_ = function(callback) {};
<|endoftext|>


<commit_before>/*jshint browserify: true */
"use strict";

var noop = require('./util/noop'),
  extend = require('extend'),
  ArangoError = require('./error');

module.exports = Collection;

function Collection(connection, body) {
  this._connection = connection;
  extend(this, body);
}

extend(Collection.prototype, {
  _get: function (path, update, callback) {
    if (!callback) callback = noop;
    var self = this;
    self._connection.get('collection/' + self.name + '/' + path, function (err, body) {
      if (err) callback(err);
      else {
        if (update) extend(self, body);
        callback(null, body);
      }
    });
  },
  _put: function (path, data, update, callback) {
    if (!callback) callback = noop;
    var self = this;
    self._connection.put('collection/' + self.name + '/' + path, data, function (err, body) {
      if (err) callback(err);
      else {
        if (update) extend(self, body);
        callback(null, body);
      }
    });
  },
  properties: function (callback) {
    return this._get('properties', true, callback);
  },
  count: function (callback) {
    return this._get('count', true, callback);
  },
  revision: function (callback) {
    return this._get('revision', true, callback);
  },
  checksum: function (callback) {
    return this._get('checksum', true, callback);
  },
  load: function (count, callback) {
    if (typeof count === 'function') {
      callback = count;
      count = undefined;
    }
    return this._put('load', (
      typeof count === 'boolean' ? {count: count} : undefined
    ), true, callback);
  },
  unload: function (callback) {
    return this._put('unload', undefined, true, callback);
  },
  setProperties: function (properties, callback) {
    return this._put('properties', properties, true, callback);
  },
  rename: function (name, callback) {
    return this._put('rename', {name: name}, true, callback);
  },
  rotate: function (callback) {
    return this._put('rotate', undefined, false, callback);
  },
  truncate: function (callback) {
    return this._put('truncate', undefined, true, callback);
  },
  drop: function (callback) {
    if (!callback) callback = noop;
    var self = this;
    self._connection.delete('collection/' + self.name, function (err, body) {
      if (err) callback(err);
      else callback(null);
    });
  },
  document: function (documentHandle, callback) {
    if (!callback) callback = noop;
    if (documentHandle.indexOf('/') === -1) {
      documentHandle = this.name + '/' + documentHandle;
    }
    this._connection.get('document/' + documentHandle, function (err, body) {
      if (err) callback(err);
      else callback(null, body);
    });
  },
  save: function (data, opts, callback) {
    if (typeof opts === 'function') {
      callback = opts;
      opts = undefined;
    }
    if (!callback) callback = noop;
    opts = extend({}, opts, {collection: this.name});
    this._connection.post('document', data, opts, function (err, body) {
      if (err) callback(err);
      else callback(null, body);
    });
  },
  replace: function (documentHandle, data, opts, callback) {
    if (typeof opts === 'function') {
      callback = opts;
      opts = undefined;
    }
    if (!callback) callback = noop;
    opts = extend({}, opts, {collection: this.name});
    if (documentHandle.indexOf('/') === -1) {
      documentHandle = this.name + '/' + documentHandle;
    }
    this._connection.put('document/' + documentHandle, data, opts, function (err, body) {
      if (err) callback(err);
      else callback(null, body);
    });
  },
  update: function (documentHandle, data, opts, callback) {
    if (typeof opts === 'function') {
      callback = opts;
      opts = undefined;
    }
    if (!callback) callback = noop;
    opts = extend({}, opts, {collection: this.name});
    if (documentHandle.indexOf('/') === -1) {
      documentHandle = this.name + '/' + documentHandle;
    }
    this._connection.patch('document/' + documentHandle, data, opts, function (err, body) {
      if (err) callback(err);
      else callback(null, body);
    });
  },
  remove: function (documentHandle, opts, callback) {
    if (typeof opts === 'function') {
      callback = opts;
      opts = undefined;
    }
    if (!callback) callback = noop;
    opts = extend({}, opts, {collection: this.name});
    if (documentHandle.indexOf('/') === -1) {
      documentHandle = this.name + '/' + documentHandle;
    }
    this._connection.delete('document/' + documentHandle, opts, function (err, body) {
      if (err) callback(err);
      else callback(null);
    });
  },
  all: function (opts, callback) {
    if (typeof opts === 'function') {
      callback = opts;
      opts = undefined;
    }
    if (!callback) callback = noop;
    opts = extend({type: 'id'}, opts, {collection: this.name});
    this._connection.get('document', opts, function (err, body) {
      if (err) callback(err);
      else callback(null, body.documents);
    });
  }
});
<commit_msg>Don't clutter collections with protocol metadata.<commit_after>/*jshint browserify: true */
"use strict";

var noop = require('./util/noop'),
  extend = require('extend'),
  ArangoError = require('./error');

module.exports = Collection;

function Collection(connection, body) {
  this._connection = connection;
  extend(this, body);
  delete this.code;
  delete this.error;
}

extend(Collection.prototype, {
  _get: function (path, update, callback) {
    if (!callback) callback = noop;
    var self = this;
    self._connection.get('collection/' + self.name + '/' + path, function (err, body) {
      if (err) callback(err);
      else {
        if (update) {
          extend(self, body);
          delete self.code;
          delete self.error;
        }
        callback(null, body);
      }
    });
  },
  _put: function (path, data, update, callback) {
    if (!callback) callback = noop;
    var self = this;
    self._connection.put('collection/' + self.name + '/' + path, data, function (err, body) {
      if (err) callback(err);
      else {
        if (update) extend(self, body);
        callback(null, body);
      }
    });
  },
  properties: function (callback) {
    return this._get('properties', true, callback);
  },
  count: function (callback) {
    return this._get('count', true, callback);
  },
  revision: function (callback) {
    return this._get('revision', true, callback);
  },
  checksum: function (callback) {
    return this._get('checksum', true, callback);
  },
  load: function (count, callback) {
    if (typeof count === 'function') {
      callback = count;
      count = undefined;
    }
    return this._put('load', (
      typeof count === 'boolean' ? {count: count} : undefined
    ), true, callback);
  },
  unload: function (callback) {
    return this._put('unload', undefined, true, callback);
  },
  setProperties: function (properties, callback) {
    return this._put('properties', properties, true, callback);
  },
  rename: function (name, callback) {
    return this._put('rename', {name: name}, true, callback);
  },
  rotate: function (callback) {
    return this._put('rotate', undefined, false, callback);
  },
  truncate: function (callback) {
    return this._put('truncate', undefined, true, callback);
  },
  drop: function (callback) {
    if (!callback) callback = noop;
    var self = this;
    self._connection.delete('collection/' + self.name, function (err, body) {
      if (err) callback(err);
      else callback(null);
    });
  },
  document: function (documentHandle, callback) {
    if (!callback) callback = noop;
    if (documentHandle.indexOf('/') === -1) {
      documentHandle = this.name + '/' + documentHandle;
    }
    this._connection.get('document/' + documentHandle, function (err, body) {
      if (err) callback(err);
      else callback(null, body);
    });
  },
  save: function (data, opts, callback) {
    if (typeof opts === 'function') {
      callback = opts;
      opts = undefined;
    }
    if (!callback) callback = noop;
    opts = extend({}, opts, {collection: this.name});
    this._connection.post('document', data, opts, function (err, body) {
      if (err) callback(err);
      else callback(null, body);
    });
  },
  replace: function (documentHandle, data, opts, callback) {
    if (typeof opts === 'function') {
      callback = opts;
      opts = undefined;
    }
    if (!callback) callback = noop;
    opts = extend({}, opts, {collection: this.name});
    if (documentHandle.indexOf('/') === -1) {
      documentHandle = this.name + '/' + documentHandle;
    }
    this._connection.put('document/' + documentHandle, data, opts, function (err, body) {
      if (err) callback(err);
      else callback(null, body);
    });
  },
  update: function (documentHandle, data, opts, callback) {
    if (typeof opts === 'function') {
      callback = opts;
      opts = undefined;
    }
    if (!callback) callback = noop;
    opts = extend({}, opts, {collection: this.name});
    if (documentHandle.indexOf('/') === -1) {
      documentHandle = this.name + '/' + documentHandle;
    }
    this._connection.patch('document/' + documentHandle, data, opts, function (err, body) {
      if (err) callback(err);
      else callback(null, body);
    });
  },
  remove: function (documentHandle, opts, callback) {
    if (typeof opts === 'function') {
      callback = opts;
      opts = undefined;
    }
    if (!callback) callback = noop;
    opts = extend({}, opts, {collection: this.name});
    if (documentHandle.indexOf('/') === -1) {
      documentHandle = this.name + '/' + documentHandle;
    }
    this._connection.delete('document/' + documentHandle, opts, function (err, body) {
      if (err) callback(err);
      else callback(null);
    });
  },
  all: function (opts, callback) {
    if (typeof opts === 'function') {
      callback = opts;
      opts = undefined;
    }
    if (!callback) callback = noop;
    opts = extend({type: 'id'}, opts, {collection: this.name});
    this._connection.get('document', opts, function (err, body) {
      if (err) callback(err);
      else callback(null, body.documents);
    });
  }
});
<|endoftext|>


<commit_before>'use strict';

var events = require('events');
var fs     = require('fs');
var http   = require('http');
var path   = require('path');
var url    = require('url');
var util   = require('util');

var merge   = require('merge');
var request = require('request');
var xml     = require('xml2js');

function WebDAVClient(options) {
  this.options = options;
  this.baseURL = url.parse(options.baseURL);
}

util.inherits(WebDAVClient, events.EventEmitter);

WebDAVClient.prototype.request = function (method, remotePath, body, callback) {
  if (typeof body === 'function') {
    callback = body;
    body     = null;
  }

  var options = (typeof method === 'string') ? {method: method} : method;

  options.url  = url.format(merge(true, this.baseURL, {pathname: path.join(this.baseURL.pathname, remotePath)}));
  options.auth = this.options.credentials;

  if (body) {
    options.body = body;
  }

  return request(options, function (err, response, responseBody) {
    if (typeof callback === 'function') {
      if (err) {
        return callback(err);
      }

      if (response.statusCode > 300) {
        var error = new Error('WebDAV request error');

        error.statusCode    = response.statusCode;
        error.statusMessage = response.statusMessage || http.STATUS_CODES[response.statusCode];

        return callback(error);
      }

      return callback(err, responseBody);
    }
  });
};

WebDAVClient.prototype.connect = function () {
  var self = this;

  request({
    method: 'OPTIONS',
    url:    url.format(self.baseURL),
    auth:   self.options.credentials
  }, function (err, response) {
    if (err) {
      self.emit('error', err);
    } else if (response.statusCode > 300) {
      var error = new Error('WebDAV request error');

      error.statusCode    = response.statusCode;
      error.statusMessage = response.statusMessage || http.STATUS_CODES[response.statusCode];

      self.emit('error', error);
    } else {
      self.emit('ready');
    }
  });
};

WebDAVClient.prototype.createReadStream = function (remotePath) {
  return this.request('GET', remotePath).on('response', function (response) {
    if (response.statusCode >= 400) {
      var error = new Error('WebDAV request error');

      error.statusCode    = response.statusCode;
      error.statusMessage = response.statusMessage || http.STATUS_CODES[response.statusCode];

      response.destroy(error);
    }
  });
};

WebDAVClient.prototype.createWriteStream = function (remotePath) {
  return this.request('PUT', remotePath).on('response', function (response) {
    if (response.statusCode >= 400) {
      var error = new Error('WebDAV request error');

      error.statusCode    = response.statusCode;
      error.statusMessage = response.statusMessage || http.STATUS_CODES[response.statusCode];

      response.destroy(error);
    }
  });
};

WebDAVClient.prototype.get = function (remote, local, callback) {
  var stream = this.createReadStream(remote).on('error', callback).pipe(fs.createWriteStream(local));

  stream.on('finish', callback);
  stream.on('error', callback);
};

WebDAVClient.prototype.mkdir = function (remotePath, mode, callback) {
  if (typeof mode === 'function') {
    callback = mode;
    mode     = null;
  }

  this.request('MKCOL', remotePath, function (error) {
    return callback(error);
  });
};

WebDAVClient.prototype.put = function (local, remote, callback) {
  var stream = fs.createReadStream(local).on('error', callback).pipe(this.createWriteStream(remote));

  stream.on('finish', callback);
  stream.on('error', callback);
};

WebDAVClient.prototype.readdir = function (remotePath, callback) {
  var basePath = path.join(this.baseURL.pathname, remotePath, '/').replace(/\//g, '\\/');
  var regexp   = new RegExp('^' + basePath);

  this.request({
    method:  'PROPFIND',
    headers: {
      'Content-Type': 'text/xml',
      'Depth':        1
    }
  }, remotePath, function (error, body) {
    if (error) {
      return callback(error);
    }

    xml.parseString(body.replace(/(<\/?)\w+:/g, '$1'), function (parseError, content) {
      if (parseError) {
        return callback(parseError);
      }

      var files = content.multistatus.response.map(function (response) {
        return response.href[0].replace(regexp, '');
      }).filter(function (file) {
        return (typeof file === 'string' && file.length > 0);
      });

      return callback(null, files);
    });
  });
};

WebDAVClient.prototype.rmdir = function (remotePath, callback) {
  if (remotePath.charAt(remotePath.length - 1) !== '/') {
    remotePath += '/';
  }

  this.request({
    method:  'DELETE',
    headers: {
      Depth: 'infinity'
    }
  }, remotePath, function (error) {
    return callback(error);
  });
};

WebDAVClient.prototype.unlink = function (remotePath, callback) {
  this.request('DELETE', remotePath, function (error) {
    return callback(error);
  });
};

module.exports = WebDAVClient;
<commit_msg>Add disconnect method to WebDAV client<commit_after>'use strict';

var events = require('events');
var fs     = require('fs');
var http   = require('http');
var path   = require('path');
var url    = require('url');
var util   = require('util');

var merge   = require('merge');
var request = require('request');
var xml     = require('xml2js');

function WebDAVClient(options) {
  this.options = options;
  this.baseURL = url.parse(options.baseURL);
}

util.inherits(WebDAVClient, events.EventEmitter);

WebDAVClient.prototype.request = function (method, remotePath, body, callback) {
  if (typeof body === 'function') {
    callback = body;
    body     = null;
  }

  var options = (typeof method === 'string') ? {method: method} : method;

  options.url  = url.format(merge(true, this.baseURL, {pathname: path.join(this.baseURL.pathname, remotePath)}));
  options.auth = this.options.credentials;

  if (body) {
    options.body = body;
  }

  return request(options, function (err, response, responseBody) {
    if (typeof callback === 'function') {
      if (err) {
        return callback(err);
      }

      if (response.statusCode > 300) {
        var error = new Error('WebDAV request error');

        error.statusCode    = response.statusCode;
        error.statusMessage = response.statusMessage || http.STATUS_CODES[response.statusCode];

        return callback(error);
      }

      return callback(err, responseBody);
    }
  });
};

WebDAVClient.prototype.connect = function () {
  var self = this;

  request({
    method: 'OPTIONS',
    url:    url.format(self.baseURL),
    auth:   self.options.credentials
  }, function (err, response) {
    if (err) {
      self.emit('error', err);
    } else if (response.statusCode > 300) {
      var error = new Error('WebDAV request error');

      error.statusCode    = response.statusCode;
      error.statusMessage = response.statusMessage || http.STATUS_CODES[response.statusCode];

      self.emit('error', error);
    } else {
      self.emit('ready');
    }
  });
};

WebDAVClient.prototype.createReadStream = function (remotePath) {
  return this.request('GET', remotePath).on('response', function (response) {
    if (response.statusCode >= 400) {
      var error = new Error('WebDAV request error');

      error.statusCode    = response.statusCode;
      error.statusMessage = response.statusMessage || http.STATUS_CODES[response.statusCode];

      response.destroy(error);
    }
  });
};

WebDAVClient.prototype.createWriteStream = function (remotePath) {
  return this.request('PUT', remotePath).on('response', function (response) {
    if (response.statusCode >= 400) {
      var error = new Error('WebDAV request error');

      error.statusCode    = response.statusCode;
      error.statusMessage = response.statusMessage || http.STATUS_CODES[response.statusCode];

      response.destroy(error);
    }
  });
};

WebDAVClient.prototype.get = function (remote, local, callback) {
  var stream = this.createReadStream(remote).on('error', callback).pipe(fs.createWriteStream(local));

  stream.on('finish', callback);
  stream.on('error', callback);
};

WebDAVClient.prototype.mkdir = function (remotePath, mode, callback) {
  if (typeof mode === 'function') {
    callback = mode;
    mode     = null;
  }

  this.request('MKCOL', remotePath, function (error) {
    return callback(error);
  });
};

WebDAVClient.prototype.put = function (local, remote, callback) {
  var stream = fs.createReadStream(local).on('error', callback).pipe(this.createWriteStream(remote));

  stream.on('finish', callback);
  stream.on('error', callback);
};

WebDAVClient.prototype.readdir = function (remotePath, callback) {
  var basePath = path.join(this.baseURL.pathname, remotePath, '/').replace(/\//g, '\\/');
  var regexp   = new RegExp('^' + basePath);

  this.request({
    method:  'PROPFIND',
    headers: {
      'Content-Type': 'text/xml',
      'Depth':        1
    }
  }, remotePath, function (error, body) {
    if (error) {
      return callback(error);
    }

    xml.parseString(body.replace(/(<\/?)\w+:/g, '$1'), function (parseError, content) {
      if (parseError) {
        return callback(parseError);
      }

      var files = content.multistatus.response.map(function (response) {
        return response.href[0].replace(regexp, '');
      }).filter(function (file) {
        return (typeof file === 'string' && file.length > 0);
      });

      return callback(null, files);
    });
  });
};

WebDAVClient.prototype.rmdir = function (remotePath, callback) {
  if (remotePath.charAt(remotePath.length - 1) !== '/') {
    remotePath += '/';
  }

  this.request({
    method:  'DELETE',
    headers: {
      Depth: 'infinity'
    }
  }, remotePath, function (error) {
    return callback(error);
  });
};

WebDAVClient.prototype.unlink = function (remotePath, callback) {
  this.request('DELETE', remotePath, function (error) {
    return callback(error);
  });
};

WebDAVClient.prototype.disconnect = function () {
  return null;
};

module.exports = WebDAVClient;
<|endoftext|>


<commit_before>(function() {

  var V_DEBUG = console.log, isObject = function(obj) {
    var type = typeof obj;
    return type === 'function' || type === 'object' && !!obj;
  }, isString = function(str) {
    return (typeof str === 'string' && str);
  }, isFunction = function(str) {
    return (typeof str === 'function');
  }, copy = function(dest, src){
    if(!isObject(dest)) dest = {};
    if(!isObject(src)) return dest;
    for(var key in src){
      if(src.hasOwnProperty(key)){
        dest[key] = src[key];
      }
    }
    return dest;
  }, extractParameters = function(str){ // https://jsfiddle.net/jv0328tp/18/
    var ar = [];
    if(typeof str === 'string' && str.length){
      var chars = str.split(','), cl = chars.length;
      var pushInto = function(n){
        chars[n] = chars[n].trim();
        var len = chars[n].length;
        //convert single quoted string to double quoted string for JSON parse
        if(len >= 2 && ((chars[n].charAt(0) === "'" && chars[n].charAt(len - 1) === "'") ||
              (chars[n].charAt(0) === '"' && chars[n].charAt(len - 1) === '"'))){
          chars[n] = '"' + chars[n].substring(1, len - 1).replace(/\"/g, '\\"') + '"';
        }
        try {
          ar.push(JSON.parse(chars[n]));
        } catch(er){
          V_DEBUG(er);
          ar.push(undefined);
        }
      };
      for(var di, si, eg, fg, n = 0; n < cl; n++){
        eg = chars[n].charAt(0);
        fg = chars[n].charAt(chars[n].length - 1);
        if(!(eg === fg && (eg === '"' || eg === "'"))){
          chars[n] = chars[n].trim();
          eg = chars[n].charAt(0);
          fg = chars[n].charAt(chars[n].length - 1);
        }
        di = chars[n].indexOf('"');
        si = chars[n].indexOf("'");
        if(((si === -1) && (di === -1)) || (eg === fg && (eg === '"' || eg === "'")) ||
          (chars[n].charAt(0) === "{" && chars[n].charAt(chars[n].length-1) === "}" &&
          (chars[n].match(/\{/g).length === chars[n].match(/\}/g).length)) ||
          (chars[n].charAt(0) === "[" && chars[n].charAt(chars[n].length-1) === "]" &&
          (chars[n].match(/\[/g).length === chars[n].match(/\]/g).length))){
          pushInto(n);
        } else if(n < (cl-1)) {
          chars[n] = chars[n] + ','+ chars[n+1];
          chars.splice(n+1,1);
          n--;
          cl--;
          continue;
        }
      }
    }
    return ar;
  };

  var VAR_MAP = {}, FUNC_MAP = {}, DEF_NOT_FOUND_MSG = 'VAR_NOT_FOUND',
      START_VAR = '{{', END_VAR = '}}', SVAR_L = START_VAR.length, EVAR_L = END_VAR.length;

  // tested here https://jsfiddle.net/zg85982k/1/

  var extractVarName = function(variable){
    return variable.substring(SVAR_L, variable.length - EVAR_L); // will remove the enclosing braces
  };

  //this method will extract all the variables available in the string
  //variable names will be having enclosing braces
  var extractVars = function(str){
    var regex = /(\{\{[a-z_A-Z0-9:\$\.\-]+\}\})+/g;
    return str.match(regex) || [];
  };

  //extract method name from input method string e.g. {{method_name("hello", "world")}}
  // will return "method_name"
  var extractMethodName = function(methodDec){
    return methodDec.substring(SVAR_L, methodDec.indexOf('('));
  };

  //this method will extract all the methods available in the string
  var extractMethods = function(str){
    var regex = /(\{\{[a-z_A-Z0-9:\-]+\(.*?\)\}\})+/g;
    return str.match(regex) || [];
  };

  //replaces a single variable (only variable) in the string, if exists
  var replaceVariable = function(str, varName, varValue){
    if(str === varName) return varValue;
    var strType = typeof varValue === "string", ln = str.length;
    return str.replace((strType || (str.indexOf('{{') !== 0 || str.indexOf('}}') !== (ln-2))) ? varName : '"'+varName+'"',
        strType ? varValue : JSON.stringify(varValue));
  };

  var getVarVal = function(varVal, varName, variablesMap){
    if(typeof variablesMap !== 'object' || !variablesMap){
      variablesMap = VAR_MAP;
    }
    if(varName.indexOf('.') !== -1){
      var spls = varName.split('.'), ln = spls.length, valFound = true;
      if(ln){
        var base = getVarVal(spls[0], spls[0], variablesMap), curVal;
        for(var j = 1; j < ln; j++){
          if(spls[j].length){
            curVal = getVarVal(spls[j], spls[j], variablesMap);
            try {
              base = base[curVal];
            } catch(er){
              valFound = false;
            }
          }
        }
        if(valFound){
          return base;
        }
      }
    }
    return variablesMap.hasOwnProperty(varName) ? variablesMap[varName] : varVal;
  };

  var replaceVariables = function(str, vars, variablesMap){
    for(var i = 0; i < vars.length; i++){
      var varName = extractVarName(vars[i]);
      str = replaceVariable(str, vars[i], getVarVal(vars[i], varName, variablesMap));
    }
    return str;
  };

  var invokeMethod = function(method, params){
    try {
      return method.apply(undefined, params);
    } catch(eri) {
      V_DEBUG(eri);
      return 'V_UTILITY_ERROR';
    }
  };

  var extractMethodParams = function(methodDec, methodName, options){
    var params = [];
    if(Array.isArray(options.prefixes)){
      copy(params, options.prefixes);
    }
    var baseDec = methodDec.substring(methodName.length + SVAR_L + 1, methodDec.length - (EVAR_L + 1)).trim();
    params = params.concat(extractParameters(baseDec));
    return params;
  };

  var getMethodValue = function(methodDec, methodName, method, options){
    var methodParams = extractMethodParams(methodDec, methodName, options);
    return invokeMethod(method, methodParams);
  };

  //invokes a single method and replaces its value in the string
  var replaceMethod = function(str, methodDec, methodName, method, options){
    var methodValue = getMethodValue(methodDec, methodName, method, options);
    if(str === methodDec) return methodValue;
    return str.replace(methodDec, methodValue);
  };

  var replaceMethods = function(str, methods, methodsMap, options){
    var methodName = "";
    for(var i = 0; i < methods.length; i++){
      methodName = extractMethodName(methods[i]);
      str = replaceMethod(str, methods[i], methodName, methodsMap[methodName] || function(){ return 'NO_UTILITY_METHOD'; }, options);
    }
    return str;
  };

  var replaceUnderDec = function(str){
    var sts = str.split(','), ln = sts.length;
    for(var z =0; z < ln; z++){
      sts[z] = replaceVariables(sts[z], extractVars(sts[z]), VAR_MAP);
    }
    return sts.join(',');
  };

  var myModule = {
    init : function(options){
      if(!isObject(options)) options = {};
      copy(VAR_MAP, options.variablesMap);
      copy(FUNC_MAP, options.functionsMap);
      if(typeof options.defaultNotFoundMsg === 'string' && options.defaultNotFoundMsg) {
        DEF_NOT_FOUND_MSG = options.defaultNotFoundMsg;
      }
      if(typeof options.V_DEBUG === 'function'){
        V_DEBUG = options.V_DEBUG;
      }
      if(typeof options.startVar === 'string' && options.startVar) {
        START_VAR = options.startVar;
        SVAR_L = START_VAR.length;
      }
      if(typeof options.endVar === 'string' && options.endVar) {
        END_VAR = options.endVar;
        EVAR_L = END_VAR.length;
      }
    },

    replace : function(str, options){
      if(!isString(str)) return str;
      if(!isObject(options)) options = {};

      str = replaceVariables(str, extractVars(str), VAR_MAP);

      //if str becomes not a string then return as it is
      if(!isString(str)) return str;

      //now in our input string, all the variables are replaced
      //now the below method will automatically find all the methods, bcoz no variables are there in the string
      return replaceMethods(str, extractMethods(str), FUNC_MAP, options);
    },

    getVars : function(){
      return VAR_MAP;
    },

    clearVars: function(){
      for (var prop in VAR_MAP) { if (VAR_MAP.hasOwnProperty(prop)) { delete VAR_MAP[prop]; } }
      VAR_MAP.$ = 0;
    },

    getFuncs : function(){
      return FUNC_MAP;
    }

  };

  var root = this;

  if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
      exports = module.exports = myModule;
    }
    exports.myModule = myModule;
  } else {
    root.myModule = myModule;
  }

  if(typeof define === 'function' && define.amd) {
    define('replaceStringModule', [], function() {
      return myModule;
    });
  }

}).call(this);
<commit_msg>lazy search<commit_after>(function() {

  var V_DEBUG = console.log, isObject = function(obj) {
    var type = typeof obj;
    return type === 'function' || type === 'object' && !!obj;
  }, isString = function(str) {
    return (typeof str === 'string' && str);
  }, isFunction = function(str) {
    return (typeof str === 'function');
  }, copy = function(dest, src){
    if(!isObject(dest)) dest = {};
    if(!isObject(src)) return dest;
    for(var key in src){
      if(src.hasOwnProperty(key)){
        dest[key] = src[key];
      }
    }
    return dest;
  }, extractParameters = function(str){ // https://jsfiddle.net/jv0328tp/18/
    var ar = [];
    if(typeof str === 'string' && str.length){
      var chars = str.split(','), cl = chars.length;
      var pushInto = function(n){
        chars[n] = chars[n].trim();
        var len = chars[n].length;
        //convert single quoted string to double quoted string for JSON parse
        if(len >= 2 && ((chars[n].charAt(0) === "'" && chars[n].charAt(len - 1) === "'") ||
              (chars[n].charAt(0) === '"' && chars[n].charAt(len - 1) === '"'))){
          chars[n] = '"' + chars[n].substring(1, len - 1).replace(/\"/g, '\\"') + '"';
        }
        try {
          ar.push(JSON.parse(chars[n]));
        } catch(er){
          V_DEBUG(er);
          ar.push(undefined);
        }
      };
      for(var di, si, eg, fg, n = 0; n < cl; n++){
        eg = chars[n].charAt(0);
        fg = chars[n].charAt(chars[n].length - 1);
        if(!(eg === fg && (eg === '"' || eg === "'"))){
          chars[n] = chars[n].trim();
          eg = chars[n].charAt(0);
          fg = chars[n].charAt(chars[n].length - 1);
        }
        di = chars[n].indexOf('"');
        si = chars[n].indexOf("'");
        if(((si === -1) && (di === -1)) || (eg === fg && (eg === '"' || eg === "'")) ||
          (chars[n].charAt(0) === "{" && chars[n].charAt(chars[n].length-1) === "}" &&
          (chars[n].match(/\{/g).length === chars[n].match(/\}/g).length)) ||
          (chars[n].charAt(0) === "[" && chars[n].charAt(chars[n].length-1) === "]" &&
          (chars[n].match(/\[/g).length === chars[n].match(/\]/g).length))){
          pushInto(n);
        } else if(n < (cl-1)) {
          chars[n] = chars[n] + ','+ chars[n+1];
          chars.splice(n+1,1);
          n--;
          cl--;
          continue;
        }
      }
    }
    return ar;
  };

  var VAR_MAP = {}, FUNC_MAP = {}, DEF_NOT_FOUND_MSG = 'VAR_NOT_FOUND',
      START_VAR = '{{', END_VAR = '}}', SVAR_L = START_VAR.length, EVAR_L = END_VAR.length;

  // tested here https://jsfiddle.net/zg85982k/1/

  var extractVarName = function(variable){
    return variable.substring(SVAR_L, variable.length - EVAR_L); // will remove the enclosing braces
  };

  //this method will extract all the variables available in the string
  //variable names will be having enclosing braces
  var extractVars = function(str){
    var regex = /(\{\{[a-z_A-Z0-9:\$\.\-]+\}\})+?/g;
    return str.match(regex) || [];
  };

  //extract method name from input method string e.g. {{method_name("hello", "world")}}
  // will return "method_name"
  var extractMethodName = function(methodDec){
    return methodDec.substring(SVAR_L, methodDec.indexOf('('));
  };

  //this method will extract all the methods available in the string
  var extractMethods = function(str){
    var regex = /(\{\{[a-z_A-Z0-9:\-]+\(.*?\)\}\})+/g;
    return str.match(regex) || [];
  };

  //replaces a single variable (only variable) in the string, if exists
  var replaceVariable = function(str, varName, varValue){
    if(str === varName) return varValue;
    var strType = typeof varValue === "string", ln = str.length;
    return str.replace((strType || (str.indexOf('{{') !== 0 || str.indexOf('}}') !== (ln-2))) ? varName : '"'+varName+'"',
        strType ? varValue : JSON.stringify(varValue));
  };

  var getVarVal = function(varVal, varName, variablesMap){
    if(typeof variablesMap !== 'object' || !variablesMap){
      variablesMap = VAR_MAP;
    }
    if(varName.indexOf('.') !== -1){
      var spls = varName.split('.'), ln = spls.length, valFound = true;
      if(ln){
        var base = getVarVal(spls[0], spls[0], variablesMap), curVal;
        for(var j = 1; j < ln; j++){
          if(spls[j].length){
            curVal = getVarVal(spls[j], spls[j], variablesMap);
            try {
              base = base[curVal];
            } catch(er){
              valFound = false;
            }
          }
        }
        if(valFound){
          return base;
        }
      }
    }
    return variablesMap.hasOwnProperty(varName) ? variablesMap[varName] : varVal;
  };

  var replaceVariables = function(str, vars, variablesMap){
    for(var i = 0; i < vars.length; i++){
      var varName = extractVarName(vars[i]);
      str = replaceVariable(str, vars[i], getVarVal(vars[i], varName, variablesMap));
    }
    return str;
  };

  var invokeMethod = function(method, params){
    try {
      return method.apply(undefined, params);
    } catch(eri) {
      V_DEBUG(eri);
      return 'V_UTILITY_ERROR';
    }
  };

  var extractMethodParams = function(methodDec, methodName, options){
    var params = [];
    if(Array.isArray(options.prefixes)){
      copy(params, options.prefixes);
    }
    var baseDec = methodDec.substring(methodName.length + SVAR_L + 1, methodDec.length - (EVAR_L + 1)).trim();
    params = params.concat(extractParameters(baseDec));
    return params;
  };

  var getMethodValue = function(methodDec, methodName, method, options){
    var methodParams = extractMethodParams(methodDec, methodName, options);
    return invokeMethod(method, methodParams);
  };

  //invokes a single method and replaces its value in the string
  var replaceMethod = function(str, methodDec, methodName, method, options){
    var methodValue = getMethodValue(methodDec, methodName, method, options);
    if(str === methodDec) return methodValue;
    return str.replace(methodDec, methodValue);
  };

  var replaceMethods = function(str, methods, methodsMap, options){
    var methodName = "";
    for(var i = 0; i < methods.length; i++){
      methodName = extractMethodName(methods[i]);
      str = replaceMethod(str, methods[i], methodName, methodsMap[methodName] || function(){ return 'NO_UTILITY_METHOD'; }, options);
    }
    return str;
  };

  var replaceUnderDec = function(str){
    var sts = str.split(','), ln = sts.length;
    for(var z =0; z < ln; z++){
      sts[z] = replaceVariables(sts[z], extractVars(sts[z]), VAR_MAP);
    }
    return sts.join(',');
  };

  var myModule = {
    init : function(options){
      if(!isObject(options)) options = {};
      copy(VAR_MAP, options.variablesMap);
      copy(FUNC_MAP, options.functionsMap);
      if(typeof options.defaultNotFoundMsg === 'string' && options.defaultNotFoundMsg) {
        DEF_NOT_FOUND_MSG = options.defaultNotFoundMsg;
      }
      if(typeof options.V_DEBUG === 'function'){
        V_DEBUG = options.V_DEBUG;
      }
      if(typeof options.startVar === 'string' && options.startVar) {
        START_VAR = options.startVar;
        SVAR_L = START_VAR.length;
      }
      if(typeof options.endVar === 'string' && options.endVar) {
        END_VAR = options.endVar;
        EVAR_L = END_VAR.length;
      }
    },

    replace : function(str, options){
      if(!isString(str)) return str;
      if(!isObject(options)) options = {};

      str = replaceVariables(str, extractVars(str), VAR_MAP);

      //if str becomes not a string then return as it is
      if(!isString(str)) return str;

      //now in our input string, all the variables are replaced
      //now the below method will automatically find all the methods, bcoz no variables are there in the string
      return replaceMethods(str, extractMethods(str), FUNC_MAP, options);
    },

    getVars : function(){
      return VAR_MAP;
    },

    clearVars: function(){
      for (var prop in VAR_MAP) { if (VAR_MAP.hasOwnProperty(prop)) { delete VAR_MAP[prop]; } }
      VAR_MAP.$ = 0;
    },

    getFuncs : function(){
      return FUNC_MAP;
    }

  };

  var root = this;

  if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
      exports = module.exports = myModule;
    }
    exports.myModule = myModule;
  } else {
    root.myModule = myModule;
  }

  if(typeof define === 'function' && define.amd) {
    define('replaceStringModule', [], function() {
      return myModule;
    });
  }

}).call(this);
<|endoftext|>