initial commit
This commit is contained in:
commit
962764c034
|
@ -0,0 +1,67 @@
|
|||
<html>
|
||||
<head>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.2.1/moment.min.js"></script>
|
||||
<script src="lazyload.js"></script>
|
||||
|
||||
<style>
|
||||
img.lazy {
|
||||
border: 1px solid black;
|
||||
margin-right: 100px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
$(function() {
|
||||
function refresh() {
|
||||
$("#cam").attr('src', $("#cam").attr('src') + "?" + new Date().getTime());
|
||||
$("#update").html(moment().format('hh:mm:ss'));
|
||||
}
|
||||
|
||||
function createImageTag(file) {
|
||||
var time = moment(file.time).format();
|
||||
return $("<img class='lazy' width='640' height='480'>")
|
||||
.attr('style', 'display:inline')
|
||||
.attr('alt', 'time: ' + time)
|
||||
.attr('title', 'time: ' + time)
|
||||
.data('original', file.name);
|
||||
}
|
||||
|
||||
function fetchHistory() {
|
||||
$.getJSON("index.json", function(data) {
|
||||
$("#history").html("");
|
||||
data.files.forEach(function(file) {
|
||||
$("#history").append(createImageTag(file));
|
||||
});
|
||||
|
||||
$("img.lazy").lazyload({
|
||||
effect: "fadeIn"
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
refresh();
|
||||
setTimeout(refresh, 1000 * 60);
|
||||
fetchHistory();
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Cam capture live feed</h2>
|
||||
<img src="image.jpg" alt="cam" id="cam">
|
||||
<p>
|
||||
<strong>DO NOT REFRESH</strong> page, happens automatically every 60 seconds.<br>
|
||||
Last update: <h3 id="update"></h3>
|
||||
</p>
|
||||
<hr>
|
||||
<h2>HOURLY Cam history</h2>
|
||||
|
||||
<div id="history">
|
||||
Fetching... Please wait.
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<script>
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
{"files":[{"name":"image.jpg","type":0,"time":1381927500000,"size":"490610","owner":"ftp","group":"ftp","userPermissions":{"read":true,"write":true,"exec":false},"groupPermissions":{"read":true,"write":false,"exec":false},"otherPermissions":{"read":true,"write":false,"exec":false}}]}
|
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
* Lazy Load - jQuery plugin for lazy loading images
|
||||
*
|
||||
* Copyright (c) 2007-2013 Mika Tuupola
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* Project home:
|
||||
* http://www.appelsiini.net/projects/lazyload
|
||||
*
|
||||
* Version: 1.9.0
|
||||
*
|
||||
*/
|
||||
|
||||
(function($, window, document, undefined) {
|
||||
var $window = $(window);
|
||||
|
||||
$.fn.lazyload = function(options) {
|
||||
var elements = this;
|
||||
var $container;
|
||||
var settings = {
|
||||
threshold : 0,
|
||||
failure_limit : 0,
|
||||
event : "scroll",
|
||||
effect : "show",
|
||||
container : window,
|
||||
data_attribute : "original",
|
||||
skip_invisible : true,
|
||||
appear : null,
|
||||
load : null,
|
||||
placeholder : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"
|
||||
};
|
||||
|
||||
function update() {
|
||||
var counter = 0;
|
||||
|
||||
elements.each(function() {
|
||||
var $this = $(this);
|
||||
if (settings.skip_invisible && !$this.is(":visible")) {
|
||||
return;
|
||||
}
|
||||
if ($.abovethetop(this, settings) ||
|
||||
$.leftofbegin(this, settings)) {
|
||||
/* Nothing. */
|
||||
} else if (!$.belowthefold(this, settings) &&
|
||||
!$.rightoffold(this, settings)) {
|
||||
$this.trigger("appear");
|
||||
/* if we found an image we'll load, reset the counter */
|
||||
counter = 0;
|
||||
} else {
|
||||
if (++counter > settings.failure_limit) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
if(options) {
|
||||
/* Maintain BC for a couple of versions. */
|
||||
if (undefined !== options.failurelimit) {
|
||||
options.failure_limit = options.failurelimit;
|
||||
delete options.failurelimit;
|
||||
}
|
||||
if (undefined !== options.effectspeed) {
|
||||
options.effect_speed = options.effectspeed;
|
||||
delete options.effectspeed;
|
||||
}
|
||||
|
||||
$.extend(settings, options);
|
||||
}
|
||||
|
||||
/* Cache container as jQuery as object. */
|
||||
$container = (settings.container === undefined ||
|
||||
settings.container === window) ? $window : $(settings.container);
|
||||
|
||||
/* Fire one scroll event per scroll. Not one scroll event per image. */
|
||||
if (0 === settings.event.indexOf("scroll")) {
|
||||
$container.bind(settings.event, function() {
|
||||
return update();
|
||||
});
|
||||
}
|
||||
|
||||
this.each(function() {
|
||||
var self = this;
|
||||
var $self = $(self);
|
||||
|
||||
self.loaded = false;
|
||||
|
||||
/* If no src attribute given use data:uri. */
|
||||
if ($self.attr("src") === undefined || $self.attr("src") === false) {
|
||||
$self.attr("src", settings.placeholder);
|
||||
}
|
||||
|
||||
/* When appear is triggered load original image. */
|
||||
$self.one("appear", function() {
|
||||
if (!this.loaded) {
|
||||
if (settings.appear) {
|
||||
var elements_left = elements.length;
|
||||
settings.appear.call(self, elements_left, settings);
|
||||
}
|
||||
$("<img />")
|
||||
.bind("load", function() {
|
||||
var original = $self.data(settings.data_attribute);
|
||||
$self.hide();
|
||||
if ($self.is("img")) {
|
||||
$self.attr("src", original);
|
||||
} else {
|
||||
$self.css("background-image", "url('" + original + "')");
|
||||
}
|
||||
$self[settings.effect](settings.effect_speed);
|
||||
|
||||
self.loaded = true;
|
||||
|
||||
/* Remove image from array so it is not looped next time. */
|
||||
var temp = $.grep(elements, function(element) {
|
||||
return !element.loaded;
|
||||
});
|
||||
elements = $(temp);
|
||||
|
||||
if (settings.load) {
|
||||
var elements_left = elements.length;
|
||||
settings.load.call(self, elements_left, settings);
|
||||
}
|
||||
})
|
||||
.attr("src", $self.data(settings.data_attribute));
|
||||
}
|
||||
});
|
||||
|
||||
/* When wanted event is triggered load original image */
|
||||
/* by triggering appear. */
|
||||
if (0 !== settings.event.indexOf("scroll")) {
|
||||
$self.bind(settings.event, function() {
|
||||
if (!self.loaded) {
|
||||
$self.trigger("appear");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/* Check if something appears when window is resized. */
|
||||
$window.bind("resize", function() {
|
||||
update();
|
||||
});
|
||||
|
||||
/* With IOS5 force loading images when navigating with back button. */
|
||||
/* Non optimal workaround. */
|
||||
if ((/iphone|ipod|ipad.*os 5/gi).test(navigator.appVersion)) {
|
||||
$window.bind("pageshow", function(event) {
|
||||
if (event.originalEvent && event.originalEvent.persisted) {
|
||||
elements.each(function() {
|
||||
$(this).trigger("appear");
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Force initial check if images should appear. */
|
||||
$(document).ready(function() {
|
||||
update();
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/* Convenience methods in jQuery namespace. */
|
||||
/* Use as $.belowthefold(element, {threshold : 100, container : window}) */
|
||||
|
||||
$.belowthefold = function(element, settings) {
|
||||
var fold;
|
||||
|
||||
if (settings.container === undefined || settings.container === window) {
|
||||
fold = (window.innerHeight ? window.innerHeight : $window.height()) + $window.scrollTop();
|
||||
} else {
|
||||
fold = $(settings.container).offset().top + $(settings.container).height();
|
||||
}
|
||||
|
||||
return fold <= $(element).offset().top - settings.threshold;
|
||||
};
|
||||
|
||||
$.rightoffold = function(element, settings) {
|
||||
var fold;
|
||||
|
||||
if (settings.container === undefined || settings.container === window) {
|
||||
fold = $window.width() + $window.scrollLeft();
|
||||
} else {
|
||||
fold = $(settings.container).offset().left + $(settings.container).width();
|
||||
}
|
||||
|
||||
return fold <= $(element).offset().left - settings.threshold;
|
||||
};
|
||||
|
||||
$.abovethetop = function(element, settings) {
|
||||
var fold;
|
||||
|
||||
if (settings.container === undefined || settings.container === window) {
|
||||
fold = $window.scrollTop();
|
||||
} else {
|
||||
fold = $(settings.container).offset().top;
|
||||
}
|
||||
|
||||
return fold >= $(element).offset().top + settings.threshold + $(element).height();
|
||||
};
|
||||
|
||||
$.leftofbegin = function(element, settings) {
|
||||
var fold;
|
||||
|
||||
if (settings.container === undefined || settings.container === window) {
|
||||
fold = $window.scrollLeft();
|
||||
} else {
|
||||
fold = $(settings.container).offset().left;
|
||||
}
|
||||
|
||||
return fold >= $(element).offset().left + settings.threshold + $(element).width();
|
||||
};
|
||||
|
||||
$.inviewport = function(element, settings) {
|
||||
return !$.rightoffold(element, settings) && !$.leftofbegin(element, settings) &&
|
||||
!$.belowthefold(element, settings) && !$.abovethetop(element, settings);
|
||||
};
|
||||
|
||||
/* Custom selectors for your convenience. */
|
||||
/* Use as $("img:below-the-fold").something() or */
|
||||
/* $("img").filter(":below-the-fold").something() which is faster */
|
||||
|
||||
$.extend($.expr[":"], {
|
||||
"below-the-fold" : function(a) { return $.belowthefold(a, {threshold : 0}); },
|
||||
"above-the-top" : function(a) { return !$.belowthefold(a, {threshold : 0}); },
|
||||
"right-of-screen": function(a) { return $.rightoffold(a, {threshold : 0}); },
|
||||
"left-of-screen" : function(a) { return !$.rightoffold(a, {threshold : 0}); },
|
||||
"in-viewport" : function(a) { return $.inviewport(a, {threshold : 0}); },
|
||||
/* Maintain BC for couple of versions. */
|
||||
"above-the-fold" : function(a) { return !$.belowthefold(a, {threshold : 0}); },
|
||||
"right-of-fold" : function(a) { return $.rightoffold(a, {threshold : 0}); },
|
||||
"left-of-fold" : function(a) { return !$.rightoffold(a, {threshold : 0}); }
|
||||
});
|
||||
|
||||
})(jQuery, window, document);
|
|
@ -0,0 +1,73 @@
|
|||
|
||||
|
||||
<video autoplay></video>
|
||||
<img src="" width="640" height="480" id="image">
|
||||
<canvas style="display:none;" width="640" height="480" ></canvas>
|
||||
|
||||
<script>
|
||||
/**
|
||||
|
||||
NodeJS server, Chrome/HTML5 client, WebSockets for transferring
|
||||
http://francisshanahan.com/index.php/2011/stream-a-webcam-using-javascript-nodejs-android-opera-mobile-web-sockets-and-html5/
|
||||
|
||||
*/
|
||||
|
||||
function setupWebSocket() {
|
||||
var ws = new WebSocket("ws://localhost:8080/");
|
||||
ws.onopen = function() {
|
||||
console.log("connected");
|
||||
}
|
||||
ws.onmessage = function(e) {
|
||||
document.getElementById("streamed").src = e.data;
|
||||
}
|
||||
return ws;
|
||||
}
|
||||
var ws = setupWebSocket();
|
||||
|
||||
// cross-platform stuff.
|
||||
window.URL = window.URL || window.webkitURL;
|
||||
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||
|
||||
navigator.mozGetUserMedia || navigator.msGetUserMedia;
|
||||
// Note: The file system has been prefixed as of Google Chrome 12:
|
||||
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
|
||||
|
||||
|
||||
var video = document.querySelector('video');
|
||||
var canvas = document.querySelector('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
var localMediaStream = null;
|
||||
|
||||
function snapshot() {
|
||||
if (localMediaStream) {
|
||||
ctx.drawImage(video, 0, 0);
|
||||
// "image/webp" works in Chrome 18. In other browsers, this will fall back to image/png.
|
||||
var image = canvas.toDataURL('image/png');
|
||||
document.querySelector('img').src = image;
|
||||
|
||||
//tryToSaveIt(image);
|
||||
ws.send(image);
|
||||
}
|
||||
}
|
||||
|
||||
function startVideo() {
|
||||
video.addEventListener('click', snapshot, false);
|
||||
setInterval(snapshot, 1000 * 60);
|
||||
// Not showing vendor prefixes or code that works cross-browser.
|
||||
navigator.getUserMedia({video: true}, function(stream) {
|
||||
video.src = window.URL.createObjectURL(stream);
|
||||
localMediaStream = stream;
|
||||
}, function(e) {
|
||||
console.log("rejected", e);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<h2>hello!</h2>
|
||||
|
||||
<a href="#" onclick="startVideo()">klik hier</a> om video te capturen.<br/>
|
||||
|
||||
<hr/>
|
||||
|
||||
<h2>Streamed image:</h2>
|
||||
|
||||
<img src="" width="640" height="480" id="streamed">
|
|
@ -0,0 +1,6 @@
|
|||
var gm = require("gm").subClass({ ImageMagick : true });
|
||||
|
||||
gm("image.jpg").quality(60).compress().write("compressed.jpg", function(e) {
|
||||
if(e) throw e; // Error: spawn ENOENT ? ImageMagick niet op PATH.
|
||||
console.log("done");
|
||||
});
|
|
@ -0,0 +1,32 @@
|
|||
var Ftp = require("jsftp"), fs = require("fs");
|
||||
|
||||
var user = "FILL ME IN";
|
||||
var pass = "FILL ME IN";
|
||||
var root = "/domains/brainbaking.com/public_html";
|
||||
|
||||
var ftp = new Ftp({
|
||||
host: "ftp.brainbaking.com",
|
||||
port: 21
|
||||
});
|
||||
|
||||
ftp.auth(user, pass, function(err, res) {
|
||||
var images = { files: [] };
|
||||
ftp.ls(root + "/cam", function(err, list) {
|
||||
|
||||
images.files = list.filter(function(file) {
|
||||
return file.name.indexOf('.jpg') > 0;
|
||||
});
|
||||
|
||||
console.log("writing " + images);
|
||||
fs.writeFile("index.json", JSON.stringify(images), function(e) {
|
||||
if(e) throw e;
|
||||
|
||||
ftp.put("index.json", root + "/cam/index.json", function(e) {
|
||||
if(e) throw e;
|
||||
console.log("written index JSON file.");
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
|
@ -0,0 +1 @@
|
|||
{"files":[{"name":"1381937362359_image.jpg","type":0,"time":1381937340000,"size":"550409","owner":"ftp","group":"ftp","userPermissions":{"read":true,"write":true,"exec":false},"groupPermissions":{"read":true,"write":false,"exec":false},"otherPermissions":{"read":true,"write":false,"exec":false}},{"name":"1381937569375_image.jpg","type":0,"time":1381937520000,"size":"586258","owner":"ftp","group":"ftp","userPermissions":{"read":true,"write":true,"exec":false},"groupPermissions":{"read":true,"write":false,"exec":false},"otherPermissions":{"read":true,"write":false,"exec":false}},{"name":"1381989036320_image.jpg","type":0,"time":1381989000000,"size":"533100","owner":"ftp","group":"ftp","userPermissions":{"read":true,"write":true,"exec":false},"groupPermissions":{"read":true,"write":false,"exec":false},"otherPermissions":{"read":true,"write":false,"exec":false}},{"name":"1381989636744_image.jpg","type":0,"time":1381989600000,"size":"633357","owner":"ftp","group":"ftp","userPermissions":{"read":true,"write":true,"exec":false},"groupPermissions":{"read":true,"write":false,"exec":false},"otherPermissions":{"read":true,"write":false,"exec":false}},{"name":"1381993235977_image.jpg","type":0,"time":1381993200000,"size":"545913","owner":"ftp","group":"ftp","userPermissions":{"read":true,"write":true,"exec":false},"groupPermissions":{"read":true,"write":false,"exec":false},"otherPermissions":{"read":true,"write":false,"exec":false}},{"name":"1381996835944_image.jpg","type":0,"time":1381996800000,"size":"543081","owner":"ftp","group":"ftp","userPermissions":{"read":true,"write":true,"exec":false},"groupPermissions":{"read":true,"write":false,"exec":false},"otherPermissions":{"read":true,"write":false,"exec":false}},{"name":"1382000435066_image.jpg","type":0,"time":1382000400000,"size":"534940","owner":"ftp","group":"ftp","userPermissions":{"read":true,"write":true,"exec":false},"groupPermissions":{"read":true,"write":false,"exec":false},"otherPermissions":{"read":true,"write":false,"exec":false}},{"name":"1382004035158_image.jpg","type":0,"time":1382004000000,"size":"543900","owner":"ftp","group":"ftp","userPermissions":{"read":true,"write":true,"exec":false},"groupPermissions":{"read":true,"write":false,"exec":false},"otherPermissions":{"read":true,"write":false,"exec":false}},{"name":"1382007635067_image.jpg","type":0,"time":1382007600000,"size":"534479","owner":"ftp","group":"ftp","userPermissions":{"read":true,"write":true,"exec":false},"groupPermissions":{"read":true,"write":false,"exec":false},"otherPermissions":{"read":true,"write":false,"exec":false}},{"name":"1382011234993_image.jpg","type":0,"time":1382011200000,"size":"535949","owner":"ftp","group":"ftp","userPermissions":{"read":true,"write":true,"exec":false},"groupPermissions":{"read":true,"write":false,"exec":false},"otherPermissions":{"read":true,"write":false,"exec":false}},{"name":"1382014835242_image.jpg","type":0,"time":1382014800000,"size":"550919","owner":"ftp","group":"ftp","userPermissions":{"read":true,"write":true,"exec":false},"groupPermissions":{"read":true,"write":false,"exec":false},"otherPermissions":{"read":true,"write":false,"exec":false}},{"name":"1382018434860_image.jpg","type":0,"time":1382018400000,"size":"523887","owner":"ftp","group":"ftp","userPermissions":{"read":true,"write":true,"exec":false},"groupPermissions":{"read":true,"write":false,"exec":false},"otherPermissions":{"read":true,"write":false,"exec":false}},{"name":"1382022034866_image.jpg","type":0,"time":1382022000000,"size":"520789","owner":"ftp","group":"ftp","userPermissions":{"read":true,"write":true,"exec":false},"groupPermissions":{"read":true,"write":false,"exec":false},"otherPermissions":{"read":true,"write":false,"exec":false}}]}
|
|
@ -0,0 +1 @@
|
|||
../ws/bin/wscat
|
|
@ -0,0 +1 @@
|
|||
jsftp
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectCodeStyleSettingsManager">
|
||||
<option name="PER_PROJECT_SETTINGS">
|
||||
<value>
|
||||
<XML>
|
||||
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
|
||||
</XML>
|
||||
</value>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
|
||||
</project>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0" is_locked="false">
|
||||
<option name="myName" value="Project Default" />
|
||||
<option name="myLocal" value="false" />
|
||||
<inspection_tool class="JasmineAdapterSupport" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
||||
<option name="processCode" value="true" />
|
||||
<option name="processLiterals" value="true" />
|
||||
<option name="processComments" value="true" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
|
@ -0,0 +1,7 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="PROJECT_PROFILE" value="Project Default" />
|
||||
<option name="USE_PROJECT_PROFILE" value="true" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptLibraryMappings">
|
||||
<file url="file://$PROJECT_DIR$" libraries="{Node.js Dependencies for jsftp}" />
|
||||
<excludedPredefinedLibrary name="HTML" />
|
||||
<excludedPredefinedLibrary name="HTML5 / EcmaScript 5" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Node.js v0.8.23 Core Modules" level="application" />
|
||||
<orderEntry type="library" name="Node.js Dependencies for jsftp" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
13
node_modules/jsftp/.idea/libraries/Node_js_Dependencies_for_jsftp.xml
generated
vendored
Normal file
13
node_modules/jsftp/.idea/libraries/Node_js_Dependencies_for_jsftp.xml
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
<component name="libraryTable">
|
||||
<library name="Node.js Dependencies for jsftp" type="javaScript">
|
||||
<properties>
|
||||
<sourceFilesUrls>
|
||||
<item url="file://$PROJECT_DIR$/node_modules" />
|
||||
</sourceFilesUrls>
|
||||
</properties>
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/node_modules" />
|
||||
</CLASSES>
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" />
|
||||
<component name="SvnConfiguration" maxAnnotateRevisions="500" myUseAcceleration="nothing" myAutoUpdateAfterCommit="false" cleanupOnStartRun="false" SSL_PROTOCOLS="sslv3">
|
||||
<option name="USER" value="" />
|
||||
<option name="PASSWORD" value="" />
|
||||
<option name="mySSHConnectionTimeout" value="30000" />
|
||||
<option name="mySSHReadTimeout" value="30000" />
|
||||
<option name="LAST_MERGED_REVISION" />
|
||||
<option name="MERGE_DRY_RUN" value="false" />
|
||||
<option name="MERGE_DIFF_USE_ANCESTRY" value="true" />
|
||||
<option name="UPDATE_LOCK_ON_DEMAND" value="false" />
|
||||
<option name="IGNORE_SPACES_IN_MERGE" value="false" />
|
||||
<option name="CHECK_NESTED_FOR_QUICK_MERGE" value="false" />
|
||||
<option name="IGNORE_SPACES_IN_ANNOTATE" value="true" />
|
||||
<option name="SHOW_MERGE_SOURCES_IN_ANNOTATE" value="true" />
|
||||
<option name="FORCE_UPDATE" value="false" />
|
||||
<option name="IGNORE_EXTERNALS" value="false" />
|
||||
<myIsUseDefaultProxy>false</myIsUseDefaultProxy>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/jsftp.iml" filepath="$PROJECT_DIR$/.idea/jsftp.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<component name="DependencyValidationManager">
|
||||
<state>
|
||||
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
|
||||
</state>
|
||||
</component>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,588 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="d32c0353-5fda-4818-910e-4e89fc5cbd7e" name="Default" comment="" />
|
||||
<ignored path="jsftp.iws" />
|
||||
<ignored path=".idea/workspace.xml" />
|
||||
<file path="/Dummy.txt" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1374064945921" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/contacts/test/unit/vcard_parsing_test.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373460050024" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/shared/test/unit/mocks/mock_navigator_moz_contact.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372423043906" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/contacts/test/unit/mock_mozContacts.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372423043906" ignored="false" />
|
||||
<file path="/vcard_parsing_test.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372235488488" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/contacts/js/utilities/vcard_parser.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373460050024" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/system/camera/js/camera.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372235729806" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/browser/js/browser.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372240712933" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/settings/js/simcard_dialog.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372423043906" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/sms/test/unit/compose_test.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372240712933" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/sms/test/unit/utils_test.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372240712933" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/sms/test/unit/thread_ui_test.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372240712933" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/ftu/js/sim_manager.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372423043906" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/ftu/js/sd_manager.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372423282581" ignored="false" />
|
||||
<file path="/vcard_parser.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372324540585" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../chords/package.json" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372337765374" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../chords/app/scripts/lib/chord.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372337656353" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../chords/app/scripts/lib/chord-simple.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372337656353" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../chords/app/index.html" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372338042258" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../chords/app/scripts/lib/angular.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372338209588" ignored="false" />
|
||||
<file path="/jsftp_test.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372416768241" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/sms/test/unit/contacts_test.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372423043906" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/ftu/test/unit/sim_manager_test.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372423043906" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/contacts/js/contacts.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/ftu/index.html" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/settings/js/wifi.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372423043906" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/contacts/test/unit/contacts_list_test.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372423043906" ignored="false" />
|
||||
<file path="/a.dummy" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372423257725" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/contacts/index.html" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200229" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/contacts/js/contacts_settings.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/contacts/style/contacts.css" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372423099652" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/contacts/test/unit/contacts_settings_test.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372452507439" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/contacts/test/unit/contacts_settings_test.js.orig" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372423116450" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/contacts/test/unit/mock_contacts_index.html" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372452507439" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/ftu/css/style.css" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372452507439" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/ftu/js/ui.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372452507439" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/ftu/test/unit/mock_ui_manager.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372423128215" ignored="false" />
|
||||
<file path="/jsftp.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372452681250" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../komposer/resources/beta/scripts/note_render.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372612711824" ignored="false" />
|
||||
<file path="$USER_HOME$/Dropbox/Jen_Sergi/Wedding!/website/index.html" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373386578888" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../komposer/resources/beta/scripts/note.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372613124837" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../komposer/resources/beta/public/BeetAnGeSample.json" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372625387169" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../komposer/src/noterious.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372669425649" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../komposer/src/note.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372669425649" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../komposer/resources/beta/public/bundle.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372669425649" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../komposer/resources/beta/scripts/lib/svg.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372669425649" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../komposer/public/js/noterious.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372669425649" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../komposer/public/js/0259ffc935b.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372669425649" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../komposer/src/measure.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372669425649" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../komposer/resources/beta/node_modules/musicjson/node_modules/sax/examples/strict.dtd" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372669425649" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../komposer/resources/beta/scripts/staff.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372674945758" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../komposer/resources/beta/scripts/main.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372669691161" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../komposer/resources/beta/scripts/stave.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372672058857" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/ftu/js/memcard_manager.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372673473010" ignored="false" />
|
||||
<file path="$USER_HOME$/Dropbox/Jen_Sergi/Wedding!/website/cat/index.html" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372942321416" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../komposer/resources/beta/package.json" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372674737893" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/staff.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372681432097" ignored="false" />
|
||||
<file path="/staff.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372681252933" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/main.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373460998794" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/public/bundle.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373461533627" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/score.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373460980383" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/stave.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373463732260" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/public/index.html" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373460544087" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/public/.bundle.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372690238813" ignored="false" />
|
||||
<file path="/score.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372693216722" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/package.json" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373459098564" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../sergi.github.com/css/screen.css" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372698454754" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../sergi.github.com/_layouts/post.html" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372698916802" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../sergi.github.com/_site/blog/atom.xml" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372698949444" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/keyboard/js/keyboard.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372942309327" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/contacts/js/contacts_details.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/contacts/js/contacts_form.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/shared/resources/apn/apns_conf_local.xml" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372758302283" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/shared/resources/apn/operator_variant.xml" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372758302283" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/contacts/js/search.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/contacts/js/contacts_shortcuts.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/test_apps/uitest/tests/keyboard_api.html" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372770223364" ignored="false" />
|
||||
<file path="/keyboard_api.html" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372768556549" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/test_apps/uitest/index.html" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200229" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/test_apps/uitest/tests/keyboard_api.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372768791173" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/profile/user.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372769834060" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/test_apps/uitest/manifest.webapp" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/test_apps/uitest/js/keyboard_api.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372769814931" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/test_apps/uitest/js/alert.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/test_apps/uitest/tests/audiotag.html" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/test_apps/uitest/js/contextmenu.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/ftu/js/language.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/test_apps/uitest/js/notification.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/test_apps/uitest/js/audiotag.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/test_apps/uitest/js/browseractivities.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/test_apps/uitest/js/empty.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/test_apps/uitest/js/identity-get.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/communications/ftu/js/wifi.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/test_apps/uitest/tests/inputmode.html" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200228" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/keyboard/js/layout.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200229" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/test_apps/uitest/tests/keyboard.html" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200229" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/test_apps/uitest/js/fullscreen.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200229" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../gaia-comoyo/apps/keyboard/js/render.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372772200229" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/lib/svg.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373281203174" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/music_json_parser.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372850628118" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/utils.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1372850628118" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/note.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373461015407" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/entity.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373461015407" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/templates.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373463310787" ignored="false" />
|
||||
<file path="/stave.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373276446450" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/test.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373281169929" ignored="false" />
|
||||
<file path="/templates.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373282058849" ignored="false" />
|
||||
<file path="/main.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373282967791" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/index.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373366191121" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/public/svg.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373371586935" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/public/lib/lib_bundle.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373366941371" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/public/lib/musicjson" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373367620732" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/build.sh" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373461533627" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/public/lib/musicjson.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373370145263" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/score_.ts" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373458708109" ignored="false" />
|
||||
<file path="/score_.ts" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373458621915" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/score_.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373459344903" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/score_.js.map" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373459344903" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/entity_.ts" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373451511732" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/entity_.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373453450283" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/stave_.ts" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373458744255" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/stave_.js.map" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373459344903" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/stave_.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373458684799" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/main_.ts" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373459179347" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/main_.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373459344903" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/svg.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373460648811" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/templates.ts" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373463306105" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/templates.js.map" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373463310787" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/entity_.js.map" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373459344903" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/main.ts" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373460998794" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/score.ts" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373463460981" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/stave.ts" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373463727892" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/entity.ts" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373461015407" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/test/score.test.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373460980383" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/entity.js.map" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373461018538" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/stave.js.map" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373463732260" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../music/scripts/score.js.map" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373462552872" ignored="false" />
|
||||
<file path="/stave.ts" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373463718951" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../birch/main.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373978563706" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../birch/js/user_list.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1373978497302" ignored="false" />
|
||||
<file path="$PROJECT_DIR$/../birch/js/filter_basic.js" changelist="d32c0353-5fda-4818-910e-4e89fc5cbd7e" time="1374064948177" ignored="false" />
|
||||
<option name="TRACKING_ENABLED" value="true" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="ChangesViewManager" flattened_view="true" show_ignored="false" />
|
||||
<component name="CreatePatchCommitExecutor">
|
||||
<option name="PATCH_PATH" value="" />
|
||||
</component>
|
||||
<component name="DaemonCodeAnalyzer">
|
||||
<disable_hints />
|
||||
</component>
|
||||
<component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
|
||||
<component name="FavoritesManager">
|
||||
<favorites_list name="jsftp" />
|
||||
</component>
|
||||
<component name="FileEditorManager">
|
||||
<leaf>
|
||||
<file leaf-file-name="jsftp.js" pinned="false" current="true" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/lib/jsftp.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="98" column="22" selection-start="2978" selection-end="2978" vertical-scroll-proportion="2.2095492">
|
||||
<folding>
|
||||
<element signature="e#5992#6447#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="response.js" pinned="false" current="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/lib/response.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="23" column="2" selection-start="567" selection-end="567" vertical-scroll-proportion="0.0">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name=".travis.yml" pinned="false" current="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/.travis.yml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="8" column="0" selection-start="106" selection-end="106" vertical-scroll-proportion="0.0">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="README.md" pinned="false" current="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/README.md">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="167" column="0" selection-start="5362" selection-end="5362" vertical-scroll-proportion="0.0">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="test.js" pinned="false" current="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/test.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="15" column="0" selection-start="490" selection-end="490" vertical-scroll-proportion="0.0">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="utils.js" pinned="false" current="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/lib/utils.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="65" column="33" selection-start="1999" selection-end="1999" vertical-scroll-proportion="0.0">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="package.json" pinned="false" current="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/package.json">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="2" column="16" selection-start="37" selection-end="37" vertical-scroll-proportion="0.0">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
</leaf>
|
||||
</component>
|
||||
<component name="FindManager">
|
||||
<FindUsagesManager>
|
||||
<setting name="OPEN_NEW_TAB" value="false" />
|
||||
</FindUsagesManager>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="GitLogSettings">
|
||||
<option name="myDateState">
|
||||
<MyDateState />
|
||||
</option>
|
||||
</component>
|
||||
<component name="IdeDocumentHistory">
|
||||
<option name="changedFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/test/parser_test.js" />
|
||||
<option value="$PROJECT_DIR$/.gitignore" />
|
||||
<option value="$PROJECT_DIR$/lib/ftpParser.js" />
|
||||
<option value="$PROJECT_DIR$/lib/handle_response.js" />
|
||||
<option value="$PROJECT_DIR$/test.js" />
|
||||
<option value="$PROJECT_DIR$/lib/utils.js" />
|
||||
<option value="$PROJECT_DIR$/.travis.yml" />
|
||||
<option value="$PROJECT_DIR$/test/basic_ftpd.py" />
|
||||
<option value="$PROJECT_DIR$/.npmignore" />
|
||||
<option value="$PROJECT_DIR$/lib/response.js" />
|
||||
<option value="$PROJECT_DIR$/Makefile" />
|
||||
<option value="$PROJECT_DIR$/LICENSE" />
|
||||
<option value="$PROJECT_DIR$/README.md" />
|
||||
<option value="$PROJECT_DIR$/package.json" />
|
||||
<option value="$PROJECT_DIR$/test/jsftp_test.js" />
|
||||
<option value="$PROJECT_DIR$/lib/jsftp.js" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectFrameBounds">
|
||||
<option name="y" value="22" />
|
||||
<option name="width" value="1440" />
|
||||
<option name="height" value="874" />
|
||||
</component>
|
||||
<component name="ProjectInspectionProfilesVisibleTreeState">
|
||||
<entry key="Project Default">
|
||||
<profile-state>
|
||||
<expanded-state>
|
||||
<State>
|
||||
<id />
|
||||
</State>
|
||||
<State>
|
||||
<id>Bitwise operation issuesJavaScript</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Control flow issuesJavaScript</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>GeneralJavaScript</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>JavaScript</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Potentially confusing code constructsJavaScript</id>
|
||||
</State>
|
||||
</expanded-state>
|
||||
</profile-state>
|
||||
</entry>
|
||||
</component>
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
||||
<OptionsSetting value="true" id="Add" />
|
||||
<OptionsSetting value="true" id="Remove" />
|
||||
<OptionsSetting value="true" id="Checkout" />
|
||||
<OptionsSetting value="true" id="Update" />
|
||||
<OptionsSetting value="true" id="Status" />
|
||||
<OptionsSetting value="true" id="Edit" />
|
||||
<ConfirmationsSetting value="1" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
<component name="ProjectReloadState">
|
||||
<option name="STATE" value="0" />
|
||||
</component>
|
||||
<component name="ProjectView">
|
||||
<navigator currentView="ProjectPane" proportions="" version="1" splitterProportion="0.5">
|
||||
<flattenPackages />
|
||||
<showMembers />
|
||||
<showModules />
|
||||
<showLibraryContents ProjectPane="true" />
|
||||
<hideEmptyPackages />
|
||||
<abbreviatePackageNames />
|
||||
<autoscrollToSource />
|
||||
<autoscrollFromSource />
|
||||
<sortByType />
|
||||
</navigator>
|
||||
<panes>
|
||||
<pane id="Scope" />
|
||||
<pane id="ProjectPane">
|
||||
<subPane>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="jsftp" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="jsftp" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="jsftp" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="jsftp" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="jsftp" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="test" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="jsftp" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="jsftp" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="lib" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
</subPane>
|
||||
</pane>
|
||||
</panes>
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="options.splitter.main.proportions" value="0.3" />
|
||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||
<property name="options.lastSelected" value="preferences.sourceCode.HTML" />
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$/../birch" />
|
||||
<property name="FullScreen" value="false" />
|
||||
<property name="options.searchVisible" value="true" />
|
||||
<property name="options.splitter.details.proportions" value="0.2" />
|
||||
<property name="GoToClass.includeJavaFiles" value="false" />
|
||||
</component>
|
||||
<component name="RunManager">
|
||||
<configuration default="true" type="NodeJSConfigurationType" factoryName="Node.js" working-dir="$PROJECT_DIR$">
|
||||
<method />
|
||||
</configuration>
|
||||
<list size="0" />
|
||||
</component>
|
||||
<component name="ShelveChangesManager" show_recycled="false" />
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="d32c0353-5fda-4818-910e-4e89fc5cbd7e" name="Default" comment="" />
|
||||
<created>1366213834349</created>
|
||||
<updated>1366213834349</updated>
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="ToolWindowManager">
|
||||
<frame x="0" y="22" width="1440" height="874" extended-state="6" />
|
||||
<editor active="false" />
|
||||
<layout>
|
||||
<window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.24982357" sideWeight="0.6700767" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.10726888" sideWeight="0.6700767" order="0" side_tool="false" content_ui="combo" />
|
||||
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32956952" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32992327" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
|
||||
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="JsTestDriver Server" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
|
||||
</layout>
|
||||
</component>
|
||||
<component name="VcsContentAnnotationSettings">
|
||||
<option name="myLimit" value="2678400000" />
|
||||
</component>
|
||||
<component name="VcsManagerConfiguration">
|
||||
<option name="OFFER_MOVE_TO_ANOTHER_CHANGELIST_ON_PARTIAL_COMMIT" value="true" />
|
||||
<option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="true" />
|
||||
<option name="CHECK_NEW_TODO" value="true" />
|
||||
<option name="myTodoPanelSettings">
|
||||
<value>
|
||||
<are-packages-shown value="false" />
|
||||
<are-modules-shown value="false" />
|
||||
<flatten-packages value="false" />
|
||||
<is-autoscroll-to-source value="false" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="PERFORM_UPDATE_IN_BACKGROUND" value="true" />
|
||||
<option name="PERFORM_COMMIT_IN_BACKGROUND" value="true" />
|
||||
<option name="PERFORM_EDIT_IN_BACKGROUND" value="true" />
|
||||
<option name="PERFORM_CHECKOUT_IN_BACKGROUND" value="true" />
|
||||
<option name="PERFORM_ADD_REMOVE_IN_BACKGROUND" value="true" />
|
||||
<option name="PERFORM_ROLLBACK_IN_BACKGROUND" value="false" />
|
||||
<option name="CHECK_LOCALLY_CHANGED_CONFLICTS_IN_BACKGROUND" value="false" />
|
||||
<option name="CHANGED_ON_SERVER_INTERVAL" value="60" />
|
||||
<option name="SHOW_ONLY_CHANGED_IN_SELECTION_DIFF" value="true" />
|
||||
<option name="CHECK_COMMIT_MESSAGE_SPELLING" value="true" />
|
||||
<option name="DEFAULT_PATCH_EXTENSION" value="patch" />
|
||||
<option name="SHORT_DIFF_HORISONTALLY" value="true" />
|
||||
<option name="SHORT_DIFF_EXTRA_LINES" value="2" />
|
||||
<option name="SOFT_WRAPS_IN_SHORT_DIFF" value="true" />
|
||||
<option name="INCLUDE_TEXT_INTO_PATCH" value="false" />
|
||||
<option name="INCLUDE_TEXT_INTO_SHELF" value="false" />
|
||||
<option name="SHOW_FILE_HISTORY_DETAILS" value="true" />
|
||||
<option name="SHOW_VCS_ERROR_NOTIFICATIONS" value="true" />
|
||||
<option name="SHOW_DIRTY_RECURSIVELY" value="false" />
|
||||
<option name="LIMIT_HISTORY" value="true" />
|
||||
<option name="MAXIMUM_HISTORY_ROWS" value="1000" />
|
||||
<option name="UPDATE_FILTER_SCOPE_NAME" />
|
||||
<option name="USE_COMMIT_MESSAGE_MARGIN" value="false" />
|
||||
<option name="COMMIT_MESSAGE_MARGIN_SIZE" value="72" />
|
||||
<option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="false" />
|
||||
<option name="FORCE_NON_EMPTY_COMMENT" value="false" />
|
||||
<option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="false" />
|
||||
<option name="LAST_COMMIT_MESSAGE" />
|
||||
<option name="MAKE_NEW_CHANGELIST_ACTIVE" value="false" />
|
||||
<option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="false" />
|
||||
<option name="CHECK_FILES_UP_TO_DATE_BEFORE_COMMIT" value="false" />
|
||||
<option name="REFORMAT_BEFORE_PROJECT_COMMIT" value="false" />
|
||||
<option name="REFORMAT_BEFORE_FILE_COMMIT" value="false" />
|
||||
<option name="FILE_HISTORY_DIALOG_COMMENTS_SPLITTER_PROPORTION" value="0.8" />
|
||||
<option name="FILE_HISTORY_DIALOG_SPLITTER_PROPORTION" value="0.5" />
|
||||
<option name="ACTIVE_VCS_NAME" />
|
||||
<option name="UPDATE_GROUP_BY_PACKAGES" value="false" />
|
||||
<option name="UPDATE_GROUP_BY_CHANGELIST" value="false" />
|
||||
<option name="UPDATE_FILTER_BY_SCOPE" value="false" />
|
||||
<option name="SHOW_FILE_HISTORY_AS_TREE" value="false" />
|
||||
<option name="FILE_HISTORY_SPLITTER_PROPORTION" value="0.6" />
|
||||
</component>
|
||||
<component name="XDebuggerManager">
|
||||
<breakpoint-manager>
|
||||
<option name="time" value="2" />
|
||||
</breakpoint-manager>
|
||||
</component>
|
||||
<component name="editorHistoryManager">
|
||||
<entry file="file://$PROJECT_DIR$/node_modules/mocha/node_modules/jade/lib/parser.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0" />
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/.gitignore">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="1" column="4" selection-start="13" selection-end="13" vertical-scroll-proportion="0.0" />
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/.npmignore">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="4" column="11" selection-start="47" selection-end="47" vertical-scroll-proportion="0.093023255" />
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/node_modules/mocha/lib/browser/events.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="5" column="0" selection-start="29" selection-end="29" vertical-scroll-proportion="0.067639254" />
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/Makefile">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="20" column="0" selection-start="607" selection-end="607" vertical-scroll-proportion="0.0" />
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/node_modules/event-stream/node_modules/split/test/split.asynct.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0" />
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/LICENSE">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="2" column="16" selection-start="33" selection-end="33" vertical-scroll-proportion="0.0" />
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/keycert.pem">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0" />
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/jsftp_test.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="108" column="11" selection-start="2561" selection-end="2561" vertical-scroll-proportion="0.022941971">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/jsftp.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="98" column="22" selection-start="2978" selection-end="2978" vertical-scroll-proportion="2.2095492">
|
||||
<folding>
|
||||
<element signature="e#5992#6447#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/response.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="23" column="2" selection-start="567" selection-end="567" vertical-scroll-proportion="0.0">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/.travis.yml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="8" column="0" selection-start="106" selection-end="106" vertical-scroll-proportion="0.0">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/README.md">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="167" column="0" selection-start="5362" selection-end="5362" vertical-scroll-proportion="0.0">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="15" column="0" selection-start="490" selection-end="490" vertical-scroll-proportion="0.0">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/utils.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="65" column="33" selection-start="1999" selection-end="1999" vertical-scroll-proportion="0.0">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/package.json">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="2" column="16" selection-start="37" selection-end="37" vertical-scroll-proportion="0.0">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
coverage.html
|
||||
*.un~
|
||||
lib-cov
|
||||
reports
|
||||
.c9revisions
|
|
@ -0,0 +1,9 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
- "0.8"
|
||||
- "0.6"
|
||||
|
||||
before_script:
|
||||
- "npm install --dev"
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
The MIT License
|
||||
|
||||
Copyright(c) 2011 Ajax.org B.V. <info AT ajax DOT org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# use the tools as dev dependencies rather than installing them globaly
|
||||
# it lets you handle specific versions of the tooling for each of your projects
|
||||
MOCHA=node_modules/.bin/mocha
|
||||
ISTANBUL=node_modules/.bin/istanbul
|
||||
JSHINT=node_modules/.bin/jshint
|
||||
|
||||
# test files must end with ".test.js"
|
||||
TESTS=$(shell find test/ -name "*.test.js")
|
||||
|
||||
clean:
|
||||
rm -rf reports
|
||||
|
||||
test:
|
||||
$(MOCHA) -R spec $(TESTS)
|
||||
|
||||
_MOCHA="node_modules/.bin/_mocha"
|
||||
coverage:
|
||||
@# check if reports folder exists, if not create it
|
||||
@test -d reports || mkdir reports
|
||||
$(ISTANBUL) cover --report lcovonly --dir ./reports $(_MOCHA) -- -R spec $(TESTS)
|
||||
genhtml reports/lcov.info --output-directory reports/
|
||||
|
||||
jshint:
|
||||
$(JSHINT) lib test --show-non-errors
|
||||
|
||||
checkstyle:
|
||||
@# check if reports folder exists, if not create it
|
||||
@test -d reports || mkdir reports
|
||||
$(JSHINT) lib test --reporter=checkstyle > reports/checkstyle.xml
|
||||
|
||||
.PHONY: clean test coverage jshint checkstyle
|
|
@ -0,0 +1,235 @@
|
|||
jsftp <a href="http://flattr.com/thing/1452098/" target="_blank"><img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this" border="0" /></a>
|
||||
=====
|
||||
|
||||
A client FTP library for NodeJS that focuses on correctness, clarity
|
||||
and conciseness. It doesn't get in the way and plays nice with streaming APIs.
|
||||
|
||||
[![NPM](https://nodei.co/npm/jsftp.png)](https://nodei.co/npm/jsftp/)
|
||||
|
||||
**Warning: The latest version (1.0.0) of jsftp breaks API compatibility with previous
|
||||
versions, it is NOT a drop-in replacement. Please be careful when upgrading. The
|
||||
API changes are not drastic at all and it is all documented below. If you do not
|
||||
want to upgrade yet you should stay with version 0.6.0, the last one before the
|
||||
upgrade. The API docs below are updated for 1.0.**
|
||||
|
||||
Starting it up
|
||||
--------------
|
||||
|
||||
```javascript
|
||||
var JSFtp = require("jsftp");
|
||||
|
||||
var Ftp = new JSFtp({
|
||||
host: "myserver.com",
|
||||
port: 3331, // defaults to 21
|
||||
user: "user", // defaults to "anonymous"
|
||||
pass: "1234" // defaults to "@anonymous"
|
||||
};
|
||||
```
|
||||
|
||||
jsftp gives you access to all the raw commands of the FTP protocol in form of
|
||||
methods in the `Ftp` object. It also provides several convenience methods for
|
||||
actions that require complex chains of commands (e.g. uploading and retrieving
|
||||
files, passive operations), as shown below.
|
||||
|
||||
When raw commands succeed they always pass the response of the server to the
|
||||
callback, in the form of an object that contains two properties: `code`, which
|
||||
is the response code of the FTP operation, and `text`, which is the complete
|
||||
text of the response.
|
||||
|
||||
Raw (or native) commands are accessible in the form `Ftp.raw["command"](params, callback)`
|
||||
|
||||
Thus, a command like `QUIT` will be called like this:
|
||||
|
||||
```javascript
|
||||
Ftp.raw.quit(function(err, data) {
|
||||
if (err) return console.error(err);
|
||||
|
||||
console.log("Bye!");
|
||||
});
|
||||
```
|
||||
|
||||
and a command like `MKD` (make directory), which accepts parameters, looks like this:
|
||||
|
||||
```javascript
|
||||
Ftp.raw.mkd("/new_dir", function(err, data) {
|
||||
if (err) return console.error(err);
|
||||
|
||||
console.log(data.text); // Show the FTP response text to the user
|
||||
console.log(data.code); // Show the FTP response code to the user
|
||||
});
|
||||
```
|
||||
|
||||
API and examples
|
||||
----------------
|
||||
|
||||
#### new Ftp(options)
|
||||
- `options` is an object with the following properties:
|
||||
|
||||
```javascript
|
||||
{
|
||||
host: 'localhost', // Host name for the current FTP server.
|
||||
port: 3333, // Port number for the current FTP server (defaults to 21).
|
||||
user: 'user', // Username
|
||||
pass: 'pass', // Password
|
||||
}
|
||||
```
|
||||
|
||||
Creates a new Ftp instance.
|
||||
|
||||
|
||||
#### Ftp.host
|
||||
|
||||
Host name for the current FTP server.
|
||||
|
||||
#### Ftp.port
|
||||
|
||||
Port number for the current FTP server (defaults to 21).
|
||||
|
||||
#### Ftp.socket
|
||||
|
||||
NodeJS socket for the current FTP server.
|
||||
|
||||
#### Ftp.features
|
||||
|
||||
Array of feature names for the current FTP server. It is
|
||||
generated when the user authenticates with the `auth` method.
|
||||
|
||||
#### Ftp.system
|
||||
|
||||
Contains the system identification string for the remote FTP server.
|
||||
|
||||
|
||||
### Methods
|
||||
|
||||
#### Ftp.raw.FTP_COMMAND([params], callback)
|
||||
All the standard FTP commands are available under the `raw` namespace. These
|
||||
commands might accept parameters or not, but they always accept a callback
|
||||
with the signature `err, data`, in which `err` is the error response coming
|
||||
from the server (usually a 4xx or 5xx error code) and the data is an object
|
||||
that contains two properties: `code` and `text`. `code` is an integer indicating
|
||||
the response code of the response and `text` is the response string itself.
|
||||
|
||||
#### Ftp.auth(username, password, callback)
|
||||
Authenticates the user with the given username and password. If null or empty
|
||||
values are passed for those, `auth` will use anonymous credentials. `callback`
|
||||
will be called with the response text in case of successful login or with an
|
||||
error as a first parameter, in normal Node fashion.
|
||||
|
||||
#### Ftp.ls(filePath, callback)
|
||||
Lists information about files or directories and yields an array of file objects
|
||||
with parsed file properties to the `callback`. You should use this function
|
||||
instead of `stat` or `list` in case you need to do something with the individual
|
||||
file properties.
|
||||
|
||||
```javascript
|
||||
ftp.ls(".", function(err, res) {
|
||||
res.forEach(function(file) {
|
||||
console.log(file.name);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
#### Ftp.list(filePath, callback)
|
||||
Lists `filePath` contents using a passive connection. Calls callback with an
|
||||
array of strings with complete file information.
|
||||
|
||||
```javascript
|
||||
ftp.list(remoteCWD, function(err, res) {
|
||||
res.forEach(function(file) {
|
||||
console.log(file.name);
|
||||
});
|
||||
// Prints something like
|
||||
// -rw-r--r-- 1 sergi staff 4 Jun 03 09:32 testfile1.txt
|
||||
// -rw-r--r-- 1 sergi staff 4 Jun 03 09:31 testfile2.txt
|
||||
// -rw-r--r-- 1 sergi staff 0 May 29 13:05 testfile3.txt
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
#### Ftp.get(remotePath, callback)
|
||||
Gives back a paused socket with the file contents ready to be streamed,
|
||||
or calls the callback with an error if not successful.
|
||||
|
||||
```javascript
|
||||
var str = ""; // Will store the contents of the file
|
||||
ftp.get('remote/path/file.txt', function(err, socket) {
|
||||
if (err) return;
|
||||
|
||||
socket.on("data", function(d) { str += d.toString(); })
|
||||
socket.on("close", function(hadErr) {
|
||||
if (hadErr)
|
||||
console.error('There was an error retrieving the file.');
|
||||
});
|
||||
socket.resume();
|
||||
});
|
||||
```
|
||||
|
||||
#### Ftp.get(remotePath, localPath, callback)
|
||||
Stores the remote file directly in the given local path.
|
||||
|
||||
```javascript
|
||||
ftp.get('remote/file.txt, 'local/file.txt, function(hadErr) {
|
||||
if (hadErr)
|
||||
console.error('There was an error retrieving the file.');
|
||||
else
|
||||
console.log('File copied successfully!');
|
||||
});
|
||||
```
|
||||
|
||||
#### Ftp.put(source, remotePath, callback)
|
||||
Uploads a file to `filePath`. It accepts a string with the local path for the
|
||||
file or a `Buffer` as a `source` parameter.
|
||||
|
||||
```javascript
|
||||
ftp.put(buffer, 'path/to/remote/file.txt', function(hadError) {
|
||||
if (!hadError)
|
||||
console.log("File transferred successfully!");
|
||||
});
|
||||
```
|
||||
|
||||
#### Ftp.rename(from, to, callback)
|
||||
Renames a file in the server. `from` and `to` are both filepaths.
|
||||
|
||||
```javascript
|
||||
ftp.rename(from, to, function(err, res) {
|
||||
if (!err)
|
||||
console.log("Renaming successful!");
|
||||
});
|
||||
```
|
||||
|
||||
#### Ftp.keepAlive()
|
||||
Refreshes the interval thats keep the server connection active.
|
||||
|
||||
You can find more usage examples in the [unit tests](https://github.com/sergi/jsftp/blob/master/test/jsftp_test.js). This documentation
|
||||
will grow as jsftp evolves.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
npm install jsftp
|
||||
|
||||
Test coverage
|
||||
-------------
|
||||
|
||||
In order to run coverage reports:
|
||||
|
||||
npm install --dev
|
||||
make coverage
|
||||
|
||||
Current overall coverage rate:
|
||||
lines......: 92.1% (316 of 343 lines)
|
||||
functions..: 91.0% (71 of 78 functions)
|
||||
|
||||
|
||||
Tests
|
||||
-----
|
||||
|
||||
To run tests:
|
||||
|
||||
npm install --dev
|
||||
make test
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
See LICENSE.
|
|
@ -0,0 +1,2 @@
|
|||
var libpath = process.env['VFS_FTP_COV'] ? './lib-cov' : './lib';
|
||||
module.exports = require(libpath + "/jsftp");
|
|
@ -0,0 +1,650 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 expandtab */
|
||||
/*global require: true module: true */
|
||||
/*
|
||||
* @package jsftp
|
||||
* @copyright Copyright(c) 2012 Ajax.org B.V. <info@c9.io>
|
||||
* @author Sergi Mansilla <sergi.mansilla@gmail.com>
|
||||
* @license https://github.com/sergi/jsFTP/blob/master/LICENSE MIT License
|
||||
*/
|
||||
|
||||
var Net = require("net");
|
||||
var EventEmitter = require("events").EventEmitter;
|
||||
var es = require("event-stream");
|
||||
var responseHandler = require("./response");
|
||||
var Utils = require("./utils");
|
||||
var util = require("util");
|
||||
var fs = require("fs");
|
||||
|
||||
var FTP_PORT = 21;
|
||||
var DEBUG_MODE = false;
|
||||
var TIMEOUT = 10 * 60 * 1000;
|
||||
var IDLE_TIME = 30000;
|
||||
var COMMANDS = [
|
||||
// Commands without parameters
|
||||
"abor", "pwd", "cdup", "feat", "noop", "quit", "pasv", "syst",
|
||||
// Commands with one or more parameters
|
||||
"cwd", "dele", "list", "mdtm", "mkd", "mode", "nlst", "pass", "retr", "rmd",
|
||||
"rnfr", "rnto", "site", "stat", "stor", "type", "user", "pass", "xrmd", "opts",
|
||||
// Extended features
|
||||
"chmod", "size"
|
||||
];
|
||||
|
||||
var Cmds = {};
|
||||
COMMANDS.forEach(function(cmd) {
|
||||
cmd = cmd.toLowerCase();
|
||||
Cmds[cmd] = function() {
|
||||
var callback = function() {};
|
||||
var completeCmd = cmd;
|
||||
if (arguments.length) {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
if (typeof args[args.length - 1] === "function")
|
||||
callback = args.pop();
|
||||
|
||||
completeCmd += " " + args.join(" ");
|
||||
}
|
||||
this.execute(completeCmd.trim(), callback);
|
||||
};
|
||||
});
|
||||
|
||||
function once(fn) {
|
||||
var returnValue, called = false;
|
||||
return function() {
|
||||
if (!called) {
|
||||
called = true;
|
||||
returnValue = fn.apply(this, arguments);
|
||||
}
|
||||
return returnValue;
|
||||
};
|
||||
}
|
||||
|
||||
var Ftp = module.exports = function(cfg) {
|
||||
"use strict";
|
||||
|
||||
Object.keys(cfg).forEach(function(opt) {
|
||||
if (!this[opt]) this[opt] = cfg[opt];
|
||||
}, this);
|
||||
|
||||
EventEmitter.call(this);
|
||||
|
||||
// True if the server doesn't support the `stat` command. Since listing a
|
||||
// directory or retrieving file properties is quite a common operation, it is
|
||||
// more efficient to avoid the round-trip to the server.
|
||||
this.useList = false;
|
||||
this.port = this.port || FTP_PORT;
|
||||
this.pending = []; // Pending requests
|
||||
this.cmdBuffer_ = [];
|
||||
this.responseHandler = responseHandler();
|
||||
|
||||
// Generate generic methods from parameter names. they can easily be
|
||||
// overriden if we need special behavior. they accept any parameters given,
|
||||
// it is the responsability of the user to validate the parameters.
|
||||
var raw = this.raw = {};
|
||||
COMMANDS.forEach(function(cmd) { raw[cmd] = Cmds[cmd].bind(this); }, this);
|
||||
|
||||
this.socket = this._createSocket(this.port, this.host);
|
||||
};
|
||||
|
||||
util.inherits(Ftp, EventEmitter);
|
||||
|
||||
Ftp.prototype.reemit = function(event) {
|
||||
var self = this;
|
||||
return function(data) { self.emit(event, data); }
|
||||
};
|
||||
|
||||
Ftp.prototype._createSocket = function(port, host, firstAction) {
|
||||
if (this.socket && this.socket.destroy) this.socket.destroy();
|
||||
|
||||
this.authenticated = false;
|
||||
var socket = Net.createConnection(port, host);
|
||||
socket.on("connect", this.reemit("connect"));
|
||||
socket.on("timeout", this.reemit("timeout"));
|
||||
|
||||
if (firstAction)
|
||||
socket.once("connect", firstAction);
|
||||
|
||||
this._createStreams(socket);
|
||||
|
||||
return socket;
|
||||
};
|
||||
|
||||
Ftp.prototype._createStreams = function(socket) {
|
||||
this.pipeline = es.pipeline(
|
||||
socket,
|
||||
es.split(),
|
||||
es.mapSync(this.responseHandler));
|
||||
|
||||
var self = this;
|
||||
this.pipeline.on('data', function(data) {
|
||||
self.emit('data', data);
|
||||
self.parseResponse.call(self, data)
|
||||
});
|
||||
this.pipeline.on("error", this.reemit("error"));
|
||||
};
|
||||
|
||||
Ftp.prototype.parseResponse = function(data) {
|
||||
if (!this.cmdBuffer_.length)
|
||||
return;
|
||||
|
||||
if ([220].indexOf(data.code) > -1)
|
||||
return;
|
||||
|
||||
var next = this.cmdBuffer_[0][1];
|
||||
if (Utils.isMark(data.code)) {
|
||||
// If we receive a Mark and it is not expected, we ignore
|
||||
// that command
|
||||
if (!next.expectsMark || next.expectsMark.marks.indexOf(data.code) === -1)
|
||||
return;
|
||||
// We might have to ignore the command that comes after the
|
||||
// mark.
|
||||
if (next.expectsMark.ignore)
|
||||
this.ignoreCmdCode = next.expectsMark.ignore;
|
||||
}
|
||||
|
||||
if (this.ignoreCmdCode && this.ignoreCmdCode === data.code) {
|
||||
this.ignoreCmdCode = null;
|
||||
return;
|
||||
}
|
||||
|
||||
this.parse(data, this.cmdBuffer_.shift());
|
||||
};
|
||||
|
||||
/**
|
||||
* Writes a new command to the server.
|
||||
*
|
||||
* @param {String} command Command to write in the FTP socket
|
||||
* @returns void
|
||||
*/
|
||||
Ftp.prototype.send = function(command) {
|
||||
if (!command || typeof command !== "string")
|
||||
return;
|
||||
|
||||
this.emit("cmdSend", command);
|
||||
this.pipeline.write(command + "\r\n");
|
||||
};
|
||||
|
||||
Ftp.prototype.nextCmd = function() {
|
||||
if (!this.inProgress && this.cmdBuffer_[0]) {
|
||||
this.send(this.cmdBuffer_[0][0]);
|
||||
this.inProgress = true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether the ftp user is authenticated at the moment of the
|
||||
* enqueing. ideally this should happen in the `push` method, just
|
||||
* before writing to the socket, but that would be complicated,
|
||||
* since we would have to 'unshift' the auth chain into the queue
|
||||
* or play the raw auth commands (that is, without enqueuing in
|
||||
* order to not mess up the queue order. ideally, that would be
|
||||
* built into the queue object. all this explanation to justify a
|
||||
* slight slopiness in the code flow.
|
||||
*
|
||||
* @param {string} action
|
||||
* @param {function} callback
|
||||
* @return void
|
||||
*/
|
||||
Ftp.prototype.execute = function(action, callback) {
|
||||
if (!callback) callback = function() {};
|
||||
|
||||
if (this.socket && this.socket.writable) {
|
||||
this._executeCommand(action, callback);
|
||||
} else {
|
||||
var self = this;
|
||||
this.authenticated = false;
|
||||
this.socket = this._createSocket(this.port, this.host, function() {
|
||||
self._executeCommand(action, callback);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Ftp.prototype._executeCommand = function(action, callback) {
|
||||
var self = this;
|
||||
|
||||
function executeCmd() {
|
||||
self.cmdBuffer_.push([action, callback]);
|
||||
self.nextCmd();
|
||||
}
|
||||
|
||||
if (self.authenticated || /feat|syst|user|pass/.test(action)) {
|
||||
executeCmd();
|
||||
} else {
|
||||
this.getFeatures(function() {
|
||||
self.auth(self.user, self.pass, executeCmd);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse is called each time that a comand and a request are paired
|
||||
* together. That is, each time that there is a round trip of actions
|
||||
* between the client and the server. The `action` param contains an array
|
||||
* with the response from the server as a first element (text) and an array
|
||||
* with the command executed and the callback (if any) as the second
|
||||
* element.
|
||||
*
|
||||
* @param action {Array} Contains server response and client command info.
|
||||
*/
|
||||
Ftp.prototype.parse = function(response, command) {
|
||||
// In FTP every response code above 399 means error in some way.
|
||||
// Since the RFC is not respected by many servers, we are going to
|
||||
// overgeneralize and consider every value above 399 as an error.
|
||||
var err = null;
|
||||
if (response.code > 399) {
|
||||
err = new Error(response.text || "Unknown FTP error.");
|
||||
err.code = response.code;
|
||||
}
|
||||
|
||||
command[1](err, response);
|
||||
this.inProgress = false;
|
||||
this.nextCmd();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the current server has the requested feature. False otherwise.
|
||||
*
|
||||
* @param {String} feature Feature to look for
|
||||
* @returns {Boolean} Whether the current server has the feature
|
||||
*/
|
||||
Ftp.prototype.hasFeat = function(feature) {
|
||||
if (feature)
|
||||
return this.features.indexOf(feature.toLowerCase()) > -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an array of features supported by the current FTP server
|
||||
*
|
||||
* @param {String} features Server response for the 'FEAT' command
|
||||
* @returns {String[]} Array of feature names
|
||||
*/
|
||||
Ftp.prototype._parseFeats = function(features) {
|
||||
// Ignore header and footer
|
||||
return features.split(/\r\n|\n/).slice(1, -1).map(function(feat) {
|
||||
return (/^\s*(\w*)\s*/).exec(feat)[1].trim().toLowerCase();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Below this point all the methods are action helpers for FTP that compose
|
||||
// several actions in one command
|
||||
|
||||
Ftp.prototype.getFeatures = function(callback) {
|
||||
var self = this;
|
||||
if (!this.features)
|
||||
this.raw.feat(function(err, response) {
|
||||
self.features = err ? [] : self._parseFeats(response.text);
|
||||
self.raw.syst(function(err, res) {
|
||||
if (!err && res.code === 215)
|
||||
self.system = res.text.toLowerCase();
|
||||
|
||||
callback(null, self.features);
|
||||
});
|
||||
});
|
||||
else
|
||||
callback(null, self.features);
|
||||
};
|
||||
|
||||
/**
|
||||
* Authenticates the user.
|
||||
*
|
||||
* @param user {String} Username
|
||||
* @param pass {String} Password
|
||||
* @param callback {Function} Follow-up function.
|
||||
*/
|
||||
Ftp.prototype.auth = function(user, pass, callback) {
|
||||
this.pending.push(callback);
|
||||
|
||||
var self = this;
|
||||
|
||||
function notifyAll(err, res) {
|
||||
var cb;
|
||||
while (cb = self.pending.shift())
|
||||
cb(err, res);
|
||||
}
|
||||
|
||||
if (this.authenticating) return;
|
||||
|
||||
if (!user) user = "anonymous";
|
||||
if (!pass) pass = "@anonymous";
|
||||
|
||||
this.authenticating = true;
|
||||
self.raw.user(user, function(err, res) {
|
||||
if (!err && [230, 331, 332].indexOf(res.code) > -1) {
|
||||
self.raw.pass(pass, function(err, res) {
|
||||
self.authenticating = false;
|
||||
|
||||
if (err)
|
||||
notifyAll(new Error("Login not accepted"));
|
||||
|
||||
if ([230, 202].indexOf(res.code) > -1) {
|
||||
self.authenticated = true;
|
||||
self.user = user;
|
||||
self.pass = pass;
|
||||
self.raw.type("I", function() {
|
||||
notifyAll(null, res);
|
||||
});
|
||||
} else if (res.code === 332) {
|
||||
self.raw.acct(""); // ACCT not really supported
|
||||
}
|
||||
});
|
||||
} else {
|
||||
self.authenticating = false;
|
||||
notifyAll(new Error("Login not accepted"));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Ftp.prototype.setType = function(type, callback) {
|
||||
if (this.type === type)
|
||||
callback(null);
|
||||
|
||||
var self = this;
|
||||
this.raw.type(type, function(err, data) {
|
||||
if (!err) self.type = type;
|
||||
|
||||
callback(err, data);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Lists a folder's contents using a passive connection.
|
||||
*
|
||||
* @param {String} [path] Remote path for the file/folder to retrieve
|
||||
* @param {Function} callback Function to call with errors or results
|
||||
*/
|
||||
Ftp.prototype.list = function(path, callback) {
|
||||
if (arguments.length === 1) {
|
||||
callback = arguments[0];
|
||||
path = "";
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var cb = function(err, listing) {
|
||||
self.setType("I", once(function() {
|
||||
callback(err, listing);
|
||||
}));
|
||||
};
|
||||
cb.expectsMark = {
|
||||
marks: [125, 150],
|
||||
ignore: 226
|
||||
};
|
||||
|
||||
var listing = "";
|
||||
this.setType("A", function() {
|
||||
self.getPasvSocket(function(err, socket) {
|
||||
socket.on("data", function(data) {
|
||||
listing += data;
|
||||
});
|
||||
socket.on("close", function(err) {
|
||||
cb(err || null, listing);
|
||||
});
|
||||
socket.on("error", cb);
|
||||
|
||||
self.send("list " + (path || ""));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Ftp.prototype.emitProgress = function(data) {
|
||||
this.emit('progress', {
|
||||
filename: data.filename,
|
||||
action: data.action,
|
||||
total: data.totalSize || 0,
|
||||
transferred: data.socket[
|
||||
data.action === 'get' ? 'bytesRead' : 'bytesWritten']
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Depending on the number of parameters, returns the content of the specified
|
||||
* file or directly saves a file into the specified destination. In the latter
|
||||
* case, an optional callback can be provided, which will receive the error in
|
||||
* case the operation was not successful.
|
||||
*
|
||||
* @param {String} remotePath File to be retrieved from the FTP server
|
||||
* @param {String} localPath Local path where the new file will be created
|
||||
* @param {Function} [callback] Gets called on either success or failure
|
||||
*/
|
||||
Ftp.prototype.get = function(remotePath, localPath, callback) {
|
||||
var self = this;
|
||||
if (arguments.length === 2) {
|
||||
callback = once(localPath || function() {});
|
||||
this.getGetSocket(remotePath, callback);
|
||||
} else {
|
||||
callback = once(callback || function() {});
|
||||
this.getGetSocket(remotePath, function(err, socket) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
}
|
||||
|
||||
var writeStream = fs.createWriteStream(localPath);
|
||||
writeStream.on('error', callback);
|
||||
|
||||
socket.on('readable', function() {
|
||||
self.emitProgress({
|
||||
filename: remotePath,
|
||||
action: 'get',
|
||||
socket: this
|
||||
});
|
||||
});
|
||||
socket.on('end', callback);
|
||||
socket.pipe(writeStream);
|
||||
socket.resume();
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a socket for a get (RETR) on a path. The socket is ready to be
|
||||
* streamed, but it is returned in a paused state. It is left to the user to
|
||||
* resume it.
|
||||
*
|
||||
* @param path {String} Path to the file to be retrieved
|
||||
* @param callback {Function} Function to call when finalized, with the socket as a parameter
|
||||
*/
|
||||
Ftp.prototype.getGetSocket = function(path, callback) {
|
||||
var self = this;
|
||||
callback = once(callback);
|
||||
this.getPasvSocket(function(err, socket) {
|
||||
if (err) return cmdCallback(err);
|
||||
|
||||
socket.pause();
|
||||
|
||||
function cmdCallback(err, res) {
|
||||
if (err) return callback(err);
|
||||
|
||||
if (res.code === 150)
|
||||
callback(null, socket);
|
||||
else
|
||||
callback(new Error("Unexpected command " + res.text));
|
||||
}
|
||||
|
||||
cmdCallback.expectsMark = {
|
||||
marks: [125, 150],
|
||||
ignore: 226
|
||||
};
|
||||
self.execute("retr " + path, cmdCallback);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Uploads contents on a FTP server. The `from` parameter can be a Buffer or the
|
||||
* path for a local file to be uploaded.
|
||||
*
|
||||
* @param {String|Buffer} from Contents to be uploaded.
|
||||
* @param {String} to path for the remote destination.
|
||||
* @param {Function} callback Function to execute on error or success.
|
||||
*/
|
||||
Ftp.prototype.put = function(from, to, callback) {
|
||||
if (from instanceof Buffer) {
|
||||
this.getPutSocket(to, function(err, socket) {
|
||||
if (!err) socket.end(from);
|
||||
}, callback);
|
||||
} else {
|
||||
var self = this;
|
||||
fs.exists(from, function(exists) {
|
||||
if (!exists)
|
||||
return callback(new Error("Local file doesn't exist."));
|
||||
|
||||
self.getPutSocket(to, function(err, socket) {
|
||||
if (err) return;
|
||||
|
||||
fs.stat(from, function(err, stats) {
|
||||
var totalSize = err ? 0 : stats.size;
|
||||
var read = fs.createReadStream(from, {
|
||||
bufferSize: 4 * 1024
|
||||
});
|
||||
read.pipe(socket);
|
||||
read.on('readable', function() {
|
||||
self.emitProgress({
|
||||
filename: to,
|
||||
action: 'put',
|
||||
socket: read,
|
||||
totalSize: totalSize
|
||||
});
|
||||
});
|
||||
});
|
||||
}, callback);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Ftp.prototype.getPutSocket = function(path, callback, doneCallback) {
|
||||
if (!callback) throw new Error("A callback argument is required.");
|
||||
|
||||
doneCallback = once(doneCallback || function() {});
|
||||
var _callback = once(function(err, _socket) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return doneCallback(err);
|
||||
}
|
||||
return callback(err, _socket);
|
||||
});
|
||||
|
||||
var self = this;
|
||||
this.getPasvSocket(function(err, socket) {
|
||||
if (err) return _callback(err);
|
||||
|
||||
var putCallback = once(function putCallback(err, res) {
|
||||
if (err) return _callback(err);
|
||||
|
||||
// Mark 150 indicates that the 'STOR' socket is ready to receive data.
|
||||
// Anything else is not relevant.
|
||||
if (res.code === 150) {
|
||||
socket.on('close', doneCallback);
|
||||
socket.on('error', doneCallback);
|
||||
_callback(null, socket);
|
||||
} else {
|
||||
return _callback(new Error("Unexpected command " + res.text));
|
||||
}
|
||||
});
|
||||
putCallback.expectsMark = {
|
||||
marks: [125, 150],
|
||||
ignore: 226
|
||||
};
|
||||
self.execute("stor " + path, putCallback);
|
||||
});
|
||||
};
|
||||
|
||||
Ftp.prototype.getPasvSocket = function(callback) {
|
||||
var timeout = this.timeout;
|
||||
callback = once(callback || function() {});
|
||||
this.execute("pasv", function(err, res) {
|
||||
if (err) return callback(err);
|
||||
|
||||
var pasvRes = Utils.getPasvPort(res.text);
|
||||
if (pasvRes === false)
|
||||
return callback(new Error("PASV: Bad host/port combination"));
|
||||
|
||||
var host = pasvRes[0];
|
||||
var port = pasvRes[1];
|
||||
var socket = Net.createConnection(port, host);
|
||||
socket.setTimeout(timeout || TIMEOUT);
|
||||
callback(null, socket);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides information about files. It lists a directory contents or
|
||||
* a single file and yields an array of file objects. The file objects
|
||||
* contain several properties. The main difference between this method and
|
||||
* 'list' or 'stat' is that it returns objects with the file properties
|
||||
* already parsed.
|
||||
*
|
||||
* Example of file object:
|
||||
*
|
||||
* {
|
||||
* name: 'README.txt',
|
||||
* type: 0,
|
||||
* time: 996052680000,
|
||||
* size: '2582',
|
||||
* owner: 'sergi',
|
||||
* group: 'staff',
|
||||
* userPermissions: { read: true, write: true, exec: false },
|
||||
* groupPermissions: { read: true, write: false, exec: false },
|
||||
* otherPermissions: { read: true, write: false, exec: false }
|
||||
* }
|
||||
*
|
||||
* The constants used in the object are defined in ftpParser.js
|
||||
*
|
||||
* @param filePath {String} Path to the file or directory to list
|
||||
* @param callback {Function} Function to call with the proper data when
|
||||
* the listing is finished.
|
||||
*/
|
||||
Ftp.prototype.ls = function(filePath, callback) {
|
||||
function entriesToList(err, entries) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
callback(null, Utils.parseEntry(entries.text || entries));
|
||||
}
|
||||
|
||||
if (this.useList) {
|
||||
this.list(filePath, entriesToList);
|
||||
} else {
|
||||
var self = this;
|
||||
this.raw.stat(filePath, function(err, data) {
|
||||
// We might be connected to a server that doesn't support the
|
||||
// 'STAT' command, which is set as default. We use 'LIST' instead,
|
||||
// and we set the variable `useList` to true, to avoid extra round
|
||||
// trips to the server to check.
|
||||
if ((err && (err.code === 502 || err.code === 500)) ||
|
||||
(self.system && self.system.indexOf("hummingbird") > -1))
|
||||
// Not sure if the "hummingbird" system check ^^^ is still
|
||||
// necessary. If they support any standards, the 500 error
|
||||
// should have us covered. Let's leave it for now.
|
||||
{
|
||||
self.useList = true;
|
||||
self.list(filePath, entriesToList);
|
||||
} else {
|
||||
entriesToList(err, data);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Ftp.prototype.rename = function(from, to, callback) {
|
||||
var self = this;
|
||||
this.raw.rnfr(from, function(err, res) {
|
||||
if (err) return callback(err);
|
||||
self.raw.rnto(to, function(err, res) {
|
||||
callback(err, res);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Ftp.prototype.keepAlive = function() {
|
||||
var self = this;
|
||||
if (this._keepAliveInterval)
|
||||
clearInterval(this._keepAliveInterval);
|
||||
|
||||
this._keepAliveInterval = setInterval(self.raw.noop, IDLE_TIME);
|
||||
};
|
||||
|
||||
Ftp.prototype.destroy = function() {
|
||||
if (this._keepAliveInterval)
|
||||
clearInterval(this._keepAliveInterval);
|
||||
|
||||
this.socket.destroy();
|
||||
this.features = null;
|
||||
this.authenticated = false;
|
||||
};
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,6 @@
|
|||
if (typeof __coverage__ === 'undefined') { __coverage__ = {}; }
|
||||
if (!__coverage__['/Users/sergi/programming/jsftp/lib/response.js']) {
|
||||
__coverage__['/Users/sergi/programming/jsftp/lib/response.js'] = {"path":"/Users/sergi/programming/jsftp/lib/response.js","s":{"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0},"b":{"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,0],"5":[0,0],"6":[0,0]},"f":{"1":0,"2":0},"fnMap":{"1":{"name":"responseHandler","line":12,"loc":{"start":{"line":12,"column":0},"end":{"line":12,"column":27}}},"2":{"name":"(anonymous_2)","line":16,"loc":{"start":{"line":16,"column":9},"end":{"line":16,"column":24}}}},"statementMap":{"1":{"start":{"line":1,"column":0},"end":{"line":1,"column":13}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":31}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":28}},"4":{"start":{"line":12,"column":0},"end":{"line":60,"column":1}},"5":{"start":{"line":13,"column":2},"end":{"line":13,"column":18}},"6":{"start":{"line":14,"column":2},"end":{"line":14,"column":22}},"7":{"start":{"line":16,"column":2},"end":{"line":60,"column":0}},"8":{"start":{"line":17,"column":4},"end":{"line":17,"column":38}},"9":{"start":{"line":18,"column":4},"end":{"line":18,"column":17}},"10":{"start":{"line":20,"column":4},"end":{"line":20,"column":13}},"11":{"start":{"line":21,"column":4},"end":{"line":58,"column":5}},"12":{"start":{"line":22,"column":6},"end":{"line":22,"column":40}},"13":{"start":{"line":24,"column":6},"end":{"line":32,"column":7}},"14":{"start":{"line":25,"column":8},"end":{"line":25,"column":26}},"15":{"start":{"line":27,"column":8},"end":{"line":31,"column":9}},"16":{"start":{"line":28,"column":10},"end":{"line":28,"column":35}},"17":{"start":{"line":29,"column":10},"end":{"line":29,"column":22}},"18":{"start":{"line":30,"column":10},"end":{"line":30,"column":26}},"19":{"start":{"line":34,"column":6},"end":{"line":34,"column":40}},"20":{"start":{"line":37,"column":6},"end":{"line":56,"column":7}},"21":{"start":{"line":38,"column":8},"end":{"line":38,"column":48}},"22":{"start":{"line":40,"column":11},"end":{"line":56,"column":7}},"23":{"start":{"line":57,"column":6},"end":{"line":57,"column":35}},"24":{"start":{"line":62,"column":0},"end":{"line":62,"column":33}}},"branchMap":{"1":{"line":21,"type":"if","locations":[{"start":{"line":21,"column":4},"end":{"line":21,"column":4}},{"start":{"line":21,"column":4},"end":{"line":21,"column":4}}]},"2":{"line":24,"type":"if","locations":[{"start":{"line":24,"column":6},"end":{"line":24,"column":6}},{"start":{"line":24,"column":6},"end":{"line":24,"column":6}}]},"3":{"line":27,"type":"if","locations":[{"start":{"line":27,"column":8},"end":{"line":27,"column":8}},{"start":{"line":27,"column":8},"end":{"line":27,"column":8}}]},"4":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":6},"end":{"line":37,"column":6}},{"start":{"line":37,"column":6},"end":{"line":37,"column":6}}]},"5":{"line":37,"type":"binary-expr","locations":[{"start":{"line":37,"column":10},"end":{"line":37,"column":24}},{"start":{"line":37,"column":29},"end":{"line":37,"column":59}}]},"6":{"line":40,"type":"if","locations":[{"start":{"line":40,"column":11},"end":{"line":40,"column":11}},{"start":{"line":40,"column":11},"end":{"line":40,"column":11}}]}}};
|
||||
}
|
||||
var __cov_Cbo7IaZZ3Ln4aLUw25DLOQ = __coverage__['/Users/sergi/programming/jsftp/lib/response.js'];
|
||||
__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['1']++;'use strict';__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['2']++;var RE_RES=/^(\d\d\d)\s(.*)/;__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['3']++;var RE_MULTI=/^(\d\d\d)-/;__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['4']++;function responseHandler(){__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.f['1']++;__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['5']++;var buffer=[];__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['6']++;var currentCode=0;__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['7']++;return function(line){__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.f['2']++;__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['8']++;var simpleRes=RE_RES.exec(line);__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['9']++;var multiRes;__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['10']++;var code;__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['11']++;if(simpleRes){__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.b['1'][0]++;__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['12']++;code=parseInt(simpleRes[1],10);__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['13']++;if(buffer.length){__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.b['2'][0]++;__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['14']++;buffer.push(line);__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['15']++;if(currentCode===code){__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.b['3'][0]++;__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['16']++;line=buffer.join('\n');__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['17']++;buffer=[];__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['18']++;currentCode=0;}else{__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.b['3'][1]++;}}else{__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.b['2'][1]++;}__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['19']++;return{code:code,text:line};}else{__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.b['1'][1]++;__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['20']++;if((__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.b['5'][0]++,!buffer.length)&&(__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.b['5'][1]++,multiRes=RE_MULTI.exec(line))){__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.b['4'][0]++;__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['21']++;currentCode=parseInt(multiRes[1],10);}else{__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.b['4'][1]++;__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['22']++;if(buffer.length){__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.b['6'][0]++;}else{__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.b['6'][1]++;}}__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['23']++;buffer.push(line.toString());}};}__cov_Cbo7IaZZ3Ln4aLUw25DLOQ.s['24']++;module.exports=responseHandler;
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,45 @@
|
|||
"use strict";
|
||||
|
||||
var RE_RES = /^(\d\d\d)\s(.*)/;
|
||||
var RE_MULTI = /^(\d\d\d)-/;
|
||||
|
||||
/**
|
||||
* Receives a stream of responses from the server and filters
|
||||
* them before pushing them back into the stream. The filtering is
|
||||
* necessary to detect multiline responses, in which several responses from
|
||||
* the server belong to a single command.
|
||||
*/
|
||||
function responseHandler() {
|
||||
var buffer = [];
|
||||
var currentCode = 0;
|
||||
|
||||
return function(line) {
|
||||
var simpleRes = RE_RES.exec(line);
|
||||
var multiRes;
|
||||
|
||||
var code;
|
||||
if (simpleRes) {
|
||||
code = parseInt(simpleRes[1], 10);
|
||||
|
||||
if (buffer.length) {
|
||||
buffer.push(line);
|
||||
|
||||
if (currentCode === code) {
|
||||
line = buffer.join("\n");
|
||||
buffer = [];
|
||||
currentCode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return { code: code, text: line };
|
||||
}
|
||||
else {
|
||||
if (!buffer.length && (multiRes = RE_MULTI.exec(line))) {
|
||||
currentCode = parseInt(multiRes[1], 10);
|
||||
}
|
||||
buffer.push(line.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = responseHandler;
|
|
@ -0,0 +1,101 @@
|
|||
var Parser = require("parse-listing");
|
||||
var async = require("async");
|
||||
|
||||
var RE_RES = /^(\d\d\d)\s(.*)/;
|
||||
var RE_MULTI = /^(\d\d\d)-/;
|
||||
var RE_SERVER_RESPONSE = /^(\d\d\d)(.*)/;
|
||||
|
||||
var Utils = module.exports = {
|
||||
// Codes from 100 to 200 are FTP marks
|
||||
isMark: function(code) {
|
||||
code = parseInt(code, 10);
|
||||
return code > 100 && code < 200;
|
||||
},
|
||||
|
||||
/**
|
||||
* Parse raw output of a file listing, trying in to clean up broken listings in
|
||||
* the process
|
||||
* @param {String} listing Raw file listing coming from a 'list' or 'stat'
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
parseEntry: function(listing) {
|
||||
var t, parsedEntry;
|
||||
var i = 0;
|
||||
var parsed = [];
|
||||
var splitEntries = listing.split(/\r\n|\n/);
|
||||
async.eachSeries(splitEntries, function(entry, next) {
|
||||
function _next() {
|
||||
i += 1;
|
||||
next();
|
||||
}
|
||||
|
||||
// Some servers include an official code-multiline sign at the beginning of
|
||||
// every string. We must strip it if that's the case.
|
||||
if (RE_MULTI.test(entry))
|
||||
entry = entry.substr(3);
|
||||
|
||||
entry = entry.trim();
|
||||
|
||||
// Filter file-listing results from 'STAT' command, since they include
|
||||
// server responses before and after the file listing.
|
||||
// Issue: https://github.com/sergi/jsftp/issues/3
|
||||
if (RE_SERVER_RESPONSE.test(entry) ||
|
||||
RE_RES.test(entry) || RE_MULTI.test(entry)) {
|
||||
return _next();
|
||||
}
|
||||
|
||||
parsedEntry = Parser.parseEntry(entry);
|
||||
if (parsedEntry === null) {
|
||||
if (splitEntries[i + 1]) {
|
||||
t = Parser.parseEntry(entry + splitEntries[i + 1]);
|
||||
if (t !== null) {
|
||||
splitEntries[i + 1] = entry + splitEntries[i + 1];
|
||||
return _next();
|
||||
}
|
||||
}
|
||||
|
||||
if (splitEntries[i - 1] && parsed.length > 0) {
|
||||
t = Parser.parseEntry(splitEntries[i - 1] + entry);
|
||||
if (t !== null) {
|
||||
parsed[parsed.length - 1] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (parsedEntry)
|
||||
parsed.push(parsedEntry)
|
||||
}
|
||||
_next();
|
||||
});
|
||||
|
||||
return parsed;
|
||||
},
|
||||
|
||||
getPasvPort: function(text) {
|
||||
var RE_PASV = /([-\d]+,[-\d]+,[-\d]+,[-\d]+),([-\d]+),([-\d]+)/;
|
||||
var match = RE_PASV.exec(text);
|
||||
if (!match) return false;
|
||||
|
||||
// Array containing the passive host and the port number
|
||||
return [match[1].replace(/,/g, "."),
|
||||
(parseInt(match[2], 10) & 255) * 256 + (parseInt(match[3], 10) & 255)];
|
||||
},
|
||||
|
||||
/**
|
||||
* Cleans up commands with potentially insecure data in them, such as
|
||||
* passwords, personal info, etc.
|
||||
*
|
||||
* @param cmd {String} Command to be sanitized
|
||||
* @returns {String} Sanitized command
|
||||
*/
|
||||
sanitize: function(cmd) {
|
||||
if (!cmd) return "";
|
||||
|
||||
var _cmd = cmd.slice(0, 5);
|
||||
if (_cmd === "pass ")
|
||||
cmd = _cmd + Array(cmd.length - 5).join("*");
|
||||
|
||||
return cmd;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2010 Caolan McMahon
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "async",
|
||||
"repo": "caolan/async",
|
||||
"description": "Higher-order functions and common patterns for asynchronous code",
|
||||
"version": "0.1.23",
|
||||
"keywords": [],
|
||||
"dependencies": {},
|
||||
"development": {},
|
||||
"main": "lib/async.js",
|
||||
"scripts": [ "lib/async.js" ]
|
||||
}
|
|
@ -0,0 +1,955 @@
|
|||
/*global setImmediate: false, setTimeout: false, console: false */
|
||||
(function () {
|
||||
|
||||
var async = {};
|
||||
|
||||
// global on the server, window in the browser
|
||||
var root, previous_async;
|
||||
|
||||
root = this;
|
||||
if (root != null) {
|
||||
previous_async = root.async;
|
||||
}
|
||||
|
||||
async.noConflict = function () {
|
||||
root.async = previous_async;
|
||||
return async;
|
||||
};
|
||||
|
||||
function only_once(fn) {
|
||||
var called = false;
|
||||
return function() {
|
||||
if (called) throw new Error("Callback was already called.");
|
||||
called = true;
|
||||
fn.apply(root, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
//// cross-browser compatiblity functions ////
|
||||
|
||||
var _each = function (arr, iterator) {
|
||||
if (arr.forEach) {
|
||||
return arr.forEach(iterator);
|
||||
}
|
||||
for (var i = 0; i < arr.length; i += 1) {
|
||||
iterator(arr[i], i, arr);
|
||||
}
|
||||
};
|
||||
|
||||
var _map = function (arr, iterator) {
|
||||
if (arr.map) {
|
||||
return arr.map(iterator);
|
||||
}
|
||||
var results = [];
|
||||
_each(arr, function (x, i, a) {
|
||||
results.push(iterator(x, i, a));
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
var _reduce = function (arr, iterator, memo) {
|
||||
if (arr.reduce) {
|
||||
return arr.reduce(iterator, memo);
|
||||
}
|
||||
_each(arr, function (x, i, a) {
|
||||
memo = iterator(memo, x, i, a);
|
||||
});
|
||||
return memo;
|
||||
};
|
||||
|
||||
var _keys = function (obj) {
|
||||
if (Object.keys) {
|
||||
return Object.keys(obj);
|
||||
}
|
||||
var keys = [];
|
||||
for (var k in obj) {
|
||||
if (obj.hasOwnProperty(k)) {
|
||||
keys.push(k);
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
};
|
||||
|
||||
//// exported async module functions ////
|
||||
|
||||
//// nextTick implementation with browser-compatible fallback ////
|
||||
if (typeof process === 'undefined' || !(process.nextTick)) {
|
||||
if (typeof setImmediate === 'function') {
|
||||
async.nextTick = function (fn) {
|
||||
// not a direct alias for IE10 compatibility
|
||||
setImmediate(fn);
|
||||
};
|
||||
async.setImmediate = async.nextTick;
|
||||
}
|
||||
else {
|
||||
async.nextTick = function (fn) {
|
||||
setTimeout(fn, 0);
|
||||
};
|
||||
async.setImmediate = async.nextTick;
|
||||
}
|
||||
}
|
||||
else {
|
||||
async.nextTick = process.nextTick;
|
||||
if (typeof setImmediate !== 'undefined') {
|
||||
async.setImmediate = setImmediate;
|
||||
}
|
||||
else {
|
||||
async.setImmediate = async.nextTick;
|
||||
}
|
||||
}
|
||||
|
||||
async.each = function (arr, iterator, callback) {
|
||||
callback = callback || function () {};
|
||||
if (!arr.length) {
|
||||
return callback();
|
||||
}
|
||||
var completed = 0;
|
||||
_each(arr, function (x) {
|
||||
iterator(x, only_once(function (err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
callback = function () {};
|
||||
}
|
||||
else {
|
||||
completed += 1;
|
||||
if (completed >= arr.length) {
|
||||
callback(null);
|
||||
}
|
||||
}
|
||||
}));
|
||||
});
|
||||
};
|
||||
async.forEach = async.each;
|
||||
|
||||
async.eachSeries = function (arr, iterator, callback) {
|
||||
callback = callback || function () {};
|
||||
if (!arr.length) {
|
||||
return callback();
|
||||
}
|
||||
var completed = 0;
|
||||
var iterate = function () {
|
||||
iterator(arr[completed], function (err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
callback = function () {};
|
||||
}
|
||||
else {
|
||||
completed += 1;
|
||||
if (completed >= arr.length) {
|
||||
callback(null);
|
||||
}
|
||||
else {
|
||||
iterate();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
iterate();
|
||||
};
|
||||
async.forEachSeries = async.eachSeries;
|
||||
|
||||
async.eachLimit = function (arr, limit, iterator, callback) {
|
||||
var fn = _eachLimit(limit);
|
||||
fn.apply(null, [arr, iterator, callback]);
|
||||
};
|
||||
async.forEachLimit = async.eachLimit;
|
||||
|
||||
var _eachLimit = function (limit) {
|
||||
|
||||
return function (arr, iterator, callback) {
|
||||
callback = callback || function () {};
|
||||
if (!arr.length || limit <= 0) {
|
||||
return callback();
|
||||
}
|
||||
var completed = 0;
|
||||
var started = 0;
|
||||
var running = 0;
|
||||
|
||||
(function replenish () {
|
||||
if (completed >= arr.length) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
while (running < limit && started < arr.length) {
|
||||
started += 1;
|
||||
running += 1;
|
||||
iterator(arr[started - 1], function (err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
callback = function () {};
|
||||
}
|
||||
else {
|
||||
completed += 1;
|
||||
running -= 1;
|
||||
if (completed >= arr.length) {
|
||||
callback();
|
||||
}
|
||||
else {
|
||||
replenish();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
var doParallel = function (fn) {
|
||||
return function () {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
return fn.apply(null, [async.each].concat(args));
|
||||
};
|
||||
};
|
||||
var doParallelLimit = function(limit, fn) {
|
||||
return function () {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
return fn.apply(null, [_eachLimit(limit)].concat(args));
|
||||
};
|
||||
};
|
||||
var doSeries = function (fn) {
|
||||
return function () {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
return fn.apply(null, [async.eachSeries].concat(args));
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
var _asyncMap = function (eachfn, arr, iterator, callback) {
|
||||
var results = [];
|
||||
arr = _map(arr, function (x, i) {
|
||||
return {index: i, value: x};
|
||||
});
|
||||
eachfn(arr, function (x, callback) {
|
||||
iterator(x.value, function (err, v) {
|
||||
results[x.index] = v;
|
||||
callback(err);
|
||||
});
|
||||
}, function (err) {
|
||||
callback(err, results);
|
||||
});
|
||||
};
|
||||
async.map = doParallel(_asyncMap);
|
||||
async.mapSeries = doSeries(_asyncMap);
|
||||
async.mapLimit = function (arr, limit, iterator, callback) {
|
||||
return _mapLimit(limit)(arr, iterator, callback);
|
||||
};
|
||||
|
||||
var _mapLimit = function(limit) {
|
||||
return doParallelLimit(limit, _asyncMap);
|
||||
};
|
||||
|
||||
// reduce only has a series version, as doing reduce in parallel won't
|
||||
// work in many situations.
|
||||
async.reduce = function (arr, memo, iterator, callback) {
|
||||
async.eachSeries(arr, function (x, callback) {
|
||||
iterator(memo, x, function (err, v) {
|
||||
memo = v;
|
||||
callback(err);
|
||||
});
|
||||
}, function (err) {
|
||||
callback(err, memo);
|
||||
});
|
||||
};
|
||||
// inject alias
|
||||
async.inject = async.reduce;
|
||||
// foldl alias
|
||||
async.foldl = async.reduce;
|
||||
|
||||
async.reduceRight = function (arr, memo, iterator, callback) {
|
||||
var reversed = _map(arr, function (x) {
|
||||
return x;
|
||||
}).reverse();
|
||||
async.reduce(reversed, memo, iterator, callback);
|
||||
};
|
||||
// foldr alias
|
||||
async.foldr = async.reduceRight;
|
||||
|
||||
var _filter = function (eachfn, arr, iterator, callback) {
|
||||
var results = [];
|
||||
arr = _map(arr, function (x, i) {
|
||||
return {index: i, value: x};
|
||||
});
|
||||
eachfn(arr, function (x, callback) {
|
||||
iterator(x.value, function (v) {
|
||||
if (v) {
|
||||
results.push(x);
|
||||
}
|
||||
callback();
|
||||
});
|
||||
}, function (err) {
|
||||
callback(_map(results.sort(function (a, b) {
|
||||
return a.index - b.index;
|
||||
}), function (x) {
|
||||
return x.value;
|
||||
}));
|
||||
});
|
||||
};
|
||||
async.filter = doParallel(_filter);
|
||||
async.filterSeries = doSeries(_filter);
|
||||
// select alias
|
||||
async.select = async.filter;
|
||||
async.selectSeries = async.filterSeries;
|
||||
|
||||
var _reject = function (eachfn, arr, iterator, callback) {
|
||||
var results = [];
|
||||
arr = _map(arr, function (x, i) {
|
||||
return {index: i, value: x};
|
||||
});
|
||||
eachfn(arr, function (x, callback) {
|
||||
iterator(x.value, function (v) {
|
||||
if (!v) {
|
||||
results.push(x);
|
||||
}
|
||||
callback();
|
||||
});
|
||||
}, function (err) {
|
||||
callback(_map(results.sort(function (a, b) {
|
||||
return a.index - b.index;
|
||||
}), function (x) {
|
||||
return x.value;
|
||||
}));
|
||||
});
|
||||
};
|
||||
async.reject = doParallel(_reject);
|
||||
async.rejectSeries = doSeries(_reject);
|
||||
|
||||
var _detect = function (eachfn, arr, iterator, main_callback) {
|
||||
eachfn(arr, function (x, callback) {
|
||||
iterator(x, function (result) {
|
||||
if (result) {
|
||||
main_callback(x);
|
||||
main_callback = function () {};
|
||||
}
|
||||
else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}, function (err) {
|
||||
main_callback();
|
||||
});
|
||||
};
|
||||
async.detect = doParallel(_detect);
|
||||
async.detectSeries = doSeries(_detect);
|
||||
|
||||
async.some = function (arr, iterator, main_callback) {
|
||||
async.each(arr, function (x, callback) {
|
||||
iterator(x, function (v) {
|
||||
if (v) {
|
||||
main_callback(true);
|
||||
main_callback = function () {};
|
||||
}
|
||||
callback();
|
||||
});
|
||||
}, function (err) {
|
||||
main_callback(false);
|
||||
});
|
||||
};
|
||||
// any alias
|
||||
async.any = async.some;
|
||||
|
||||
async.every = function (arr, iterator, main_callback) {
|
||||
async.each(arr, function (x, callback) {
|
||||
iterator(x, function (v) {
|
||||
if (!v) {
|
||||
main_callback(false);
|
||||
main_callback = function () {};
|
||||
}
|
||||
callback();
|
||||
});
|
||||
}, function (err) {
|
||||
main_callback(true);
|
||||
});
|
||||
};
|
||||
// all alias
|
||||
async.all = async.every;
|
||||
|
||||
async.sortBy = function (arr, iterator, callback) {
|
||||
async.map(arr, function (x, callback) {
|
||||
iterator(x, function (err, criteria) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
}
|
||||
else {
|
||||
callback(null, {value: x, criteria: criteria});
|
||||
}
|
||||
});
|
||||
}, function (err, results) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
else {
|
||||
var fn = function (left, right) {
|
||||
var a = left.criteria, b = right.criteria;
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
};
|
||||
callback(null, _map(results.sort(fn), function (x) {
|
||||
return x.value;
|
||||
}));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
async.auto = function (tasks, callback) {
|
||||
callback = callback || function () {};
|
||||
var keys = _keys(tasks);
|
||||
if (!keys.length) {
|
||||
return callback(null);
|
||||
}
|
||||
|
||||
var results = {};
|
||||
|
||||
var listeners = [];
|
||||
var addListener = function (fn) {
|
||||
listeners.unshift(fn);
|
||||
};
|
||||
var removeListener = function (fn) {
|
||||
for (var i = 0; i < listeners.length; i += 1) {
|
||||
if (listeners[i] === fn) {
|
||||
listeners.splice(i, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
var taskComplete = function () {
|
||||
_each(listeners.slice(0), function (fn) {
|
||||
fn();
|
||||
});
|
||||
};
|
||||
|
||||
addListener(function () {
|
||||
if (_keys(results).length === keys.length) {
|
||||
callback(null, results);
|
||||
callback = function () {};
|
||||
}
|
||||
});
|
||||
|
||||
_each(keys, function (k) {
|
||||
var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k];
|
||||
var taskCallback = function (err) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
if (args.length <= 1) {
|
||||
args = args[0];
|
||||
}
|
||||
if (err) {
|
||||
var safeResults = {};
|
||||
_each(_keys(results), function(rkey) {
|
||||
safeResults[rkey] = results[rkey];
|
||||
});
|
||||
safeResults[k] = args;
|
||||
callback(err, safeResults);
|
||||
// stop subsequent errors hitting callback multiple times
|
||||
callback = function () {};
|
||||
}
|
||||
else {
|
||||
results[k] = args;
|
||||
async.setImmediate(taskComplete);
|
||||
}
|
||||
};
|
||||
var requires = task.slice(0, Math.abs(task.length - 1)) || [];
|
||||
var ready = function () {
|
||||
return _reduce(requires, function (a, x) {
|
||||
return (a && results.hasOwnProperty(x));
|
||||
}, true) && !results.hasOwnProperty(k);
|
||||
};
|
||||
if (ready()) {
|
||||
task[task.length - 1](taskCallback, results);
|
||||
}
|
||||
else {
|
||||
var listener = function () {
|
||||
if (ready()) {
|
||||
removeListener(listener);
|
||||
task[task.length - 1](taskCallback, results);
|
||||
}
|
||||
};
|
||||
addListener(listener);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
async.waterfall = function (tasks, callback) {
|
||||
callback = callback || function () {};
|
||||
if (tasks.constructor !== Array) {
|
||||
var err = new Error('First argument to waterfall must be an array of functions');
|
||||
return callback(err);
|
||||
}
|
||||
if (!tasks.length) {
|
||||
return callback();
|
||||
}
|
||||
var wrapIterator = function (iterator) {
|
||||
return function (err) {
|
||||
if (err) {
|
||||
callback.apply(null, arguments);
|
||||
callback = function () {};
|
||||
}
|
||||
else {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
var next = iterator.next();
|
||||
if (next) {
|
||||
args.push(wrapIterator(next));
|
||||
}
|
||||
else {
|
||||
args.push(callback);
|
||||
}
|
||||
async.setImmediate(function () {
|
||||
iterator.apply(null, args);
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
wrapIterator(async.iterator(tasks))();
|
||||
};
|
||||
|
||||
var _parallel = function(eachfn, tasks, callback) {
|
||||
callback = callback || function () {};
|
||||
if (tasks.constructor === Array) {
|
||||
eachfn.map(tasks, function (fn, callback) {
|
||||
if (fn) {
|
||||
fn(function (err) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
if (args.length <= 1) {
|
||||
args = args[0];
|
||||
}
|
||||
callback.call(null, err, args);
|
||||
});
|
||||
}
|
||||
}, callback);
|
||||
}
|
||||
else {
|
||||
var results = {};
|
||||
eachfn.each(_keys(tasks), function (k, callback) {
|
||||
tasks[k](function (err) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
if (args.length <= 1) {
|
||||
args = args[0];
|
||||
}
|
||||
results[k] = args;
|
||||
callback(err);
|
||||
});
|
||||
}, function (err) {
|
||||
callback(err, results);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
async.parallel = function (tasks, callback) {
|
||||
_parallel({ map: async.map, each: async.each }, tasks, callback);
|
||||
};
|
||||
|
||||
async.parallelLimit = function(tasks, limit, callback) {
|
||||
_parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback);
|
||||
};
|
||||
|
||||
async.series = function (tasks, callback) {
|
||||
callback = callback || function () {};
|
||||
if (tasks.constructor === Array) {
|
||||
async.mapSeries(tasks, function (fn, callback) {
|
||||
if (fn) {
|
||||
fn(function (err) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
if (args.length <= 1) {
|
||||
args = args[0];
|
||||
}
|
||||
callback.call(null, err, args);
|
||||
});
|
||||
}
|
||||
}, callback);
|
||||
}
|
||||
else {
|
||||
var results = {};
|
||||
async.eachSeries(_keys(tasks), function (k, callback) {
|
||||
tasks[k](function (err) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
if (args.length <= 1) {
|
||||
args = args[0];
|
||||
}
|
||||
results[k] = args;
|
||||
callback(err);
|
||||
});
|
||||
}, function (err) {
|
||||
callback(err, results);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
async.iterator = function (tasks) {
|
||||
var makeCallback = function (index) {
|
||||
var fn = function () {
|
||||
if (tasks.length) {
|
||||
tasks[index].apply(null, arguments);
|
||||
}
|
||||
return fn.next();
|
||||
};
|
||||
fn.next = function () {
|
||||
return (index < tasks.length - 1) ? makeCallback(index + 1): null;
|
||||
};
|
||||
return fn;
|
||||
};
|
||||
return makeCallback(0);
|
||||
};
|
||||
|
||||
async.apply = function (fn) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
return function () {
|
||||
return fn.apply(
|
||||
null, args.concat(Array.prototype.slice.call(arguments))
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
var _concat = function (eachfn, arr, fn, callback) {
|
||||
var r = [];
|
||||
eachfn(arr, function (x, cb) {
|
||||
fn(x, function (err, y) {
|
||||
r = r.concat(y || []);
|
||||
cb(err);
|
||||
});
|
||||
}, function (err) {
|
||||
callback(err, r);
|
||||
});
|
||||
};
|
||||
async.concat = doParallel(_concat);
|
||||
async.concatSeries = doSeries(_concat);
|
||||
|
||||
async.whilst = function (test, iterator, callback) {
|
||||
if (test()) {
|
||||
iterator(function (err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
async.whilst(test, iterator, callback);
|
||||
});
|
||||
}
|
||||
else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
async.doWhilst = function (iterator, test, callback) {
|
||||
iterator(function (err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
if (test()) {
|
||||
async.doWhilst(iterator, test, callback);
|
||||
}
|
||||
else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
async.until = function (test, iterator, callback) {
|
||||
if (!test()) {
|
||||
iterator(function (err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
async.until(test, iterator, callback);
|
||||
});
|
||||
}
|
||||
else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
async.doUntil = function (iterator, test, callback) {
|
||||
iterator(function (err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
if (!test()) {
|
||||
async.doUntil(iterator, test, callback);
|
||||
}
|
||||
else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
async.queue = function (worker, concurrency) {
|
||||
if (concurrency === undefined) {
|
||||
concurrency = 1;
|
||||
}
|
||||
function _insert(q, data, pos, callback) {
|
||||
if(data.constructor !== Array) {
|
||||
data = [data];
|
||||
}
|
||||
_each(data, function(task) {
|
||||
var item = {
|
||||
data: task,
|
||||
callback: typeof callback === 'function' ? callback : null
|
||||
};
|
||||
|
||||
if (pos) {
|
||||
q.tasks.unshift(item);
|
||||
} else {
|
||||
q.tasks.push(item);
|
||||
}
|
||||
|
||||
if (q.saturated && q.tasks.length === concurrency) {
|
||||
q.saturated();
|
||||
}
|
||||
async.setImmediate(q.process);
|
||||
});
|
||||
}
|
||||
|
||||
var workers = 0;
|
||||
var q = {
|
||||
tasks: [],
|
||||
concurrency: concurrency,
|
||||
saturated: null,
|
||||
empty: null,
|
||||
drain: null,
|
||||
push: function (data, callback) {
|
||||
_insert(q, data, false, callback);
|
||||
},
|
||||
unshift: function (data, callback) {
|
||||
_insert(q, data, true, callback);
|
||||
},
|
||||
process: function () {
|
||||
if (workers < q.concurrency && q.tasks.length) {
|
||||
var task = q.tasks.shift();
|
||||
if (q.empty && q.tasks.length === 0) {
|
||||
q.empty();
|
||||
}
|
||||
workers += 1;
|
||||
var next = function () {
|
||||
workers -= 1;
|
||||
if (task.callback) {
|
||||
task.callback.apply(task, arguments);
|
||||
}
|
||||
if (q.drain && q.tasks.length + workers === 0) {
|
||||
q.drain();
|
||||
}
|
||||
q.process();
|
||||
};
|
||||
var cb = only_once(next);
|
||||
worker(task.data, cb);
|
||||
}
|
||||
},
|
||||
length: function () {
|
||||
return q.tasks.length;
|
||||
},
|
||||
running: function () {
|
||||
return workers;
|
||||
}
|
||||
};
|
||||
return q;
|
||||
};
|
||||
|
||||
async.cargo = function (worker, payload) {
|
||||
var working = false,
|
||||
tasks = [];
|
||||
|
||||
var cargo = {
|
||||
tasks: tasks,
|
||||
payload: payload,
|
||||
saturated: null,
|
||||
empty: null,
|
||||
drain: null,
|
||||
push: function (data, callback) {
|
||||
if(data.constructor !== Array) {
|
||||
data = [data];
|
||||
}
|
||||
_each(data, function(task) {
|
||||
tasks.push({
|
||||
data: task,
|
||||
callback: typeof callback === 'function' ? callback : null
|
||||
});
|
||||
if (cargo.saturated && tasks.length === payload) {
|
||||
cargo.saturated();
|
||||
}
|
||||
});
|
||||
async.setImmediate(cargo.process);
|
||||
},
|
||||
process: function process() {
|
||||
if (working) return;
|
||||
if (tasks.length === 0) {
|
||||
if(cargo.drain) cargo.drain();
|
||||
return;
|
||||
}
|
||||
|
||||
var ts = typeof payload === 'number'
|
||||
? tasks.splice(0, payload)
|
||||
: tasks.splice(0);
|
||||
|
||||
var ds = _map(ts, function (task) {
|
||||
return task.data;
|
||||
});
|
||||
|
||||
if(cargo.empty) cargo.empty();
|
||||
working = true;
|
||||
worker(ds, function () {
|
||||
working = false;
|
||||
|
||||
var args = arguments;
|
||||
_each(ts, function (data) {
|
||||
if (data.callback) {
|
||||
data.callback.apply(null, args);
|
||||
}
|
||||
});
|
||||
|
||||
process();
|
||||
});
|
||||
},
|
||||
length: function () {
|
||||
return tasks.length;
|
||||
},
|
||||
running: function () {
|
||||
return working;
|
||||
}
|
||||
};
|
||||
return cargo;
|
||||
};
|
||||
|
||||
var _console_fn = function (name) {
|
||||
return function (fn) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
fn.apply(null, args.concat([function (err) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
if (typeof console !== 'undefined') {
|
||||
if (err) {
|
||||
if (console.error) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
else if (console[name]) {
|
||||
_each(args, function (x) {
|
||||
console[name](x);
|
||||
});
|
||||
}
|
||||
}
|
||||
}]));
|
||||
};
|
||||
};
|
||||
async.log = _console_fn('log');
|
||||
async.dir = _console_fn('dir');
|
||||
/*async.info = _console_fn('info');
|
||||
async.warn = _console_fn('warn');
|
||||
async.error = _console_fn('error');*/
|
||||
|
||||
async.memoize = function (fn, hasher) {
|
||||
var memo = {};
|
||||
var queues = {};
|
||||
hasher = hasher || function (x) {
|
||||
return x;
|
||||
};
|
||||
var memoized = function () {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var callback = args.pop();
|
||||
var key = hasher.apply(null, args);
|
||||
if (key in memo) {
|
||||
callback.apply(null, memo[key]);
|
||||
}
|
||||
else if (key in queues) {
|
||||
queues[key].push(callback);
|
||||
}
|
||||
else {
|
||||
queues[key] = [callback];
|
||||
fn.apply(null, args.concat([function () {
|
||||
memo[key] = arguments;
|
||||
var q = queues[key];
|
||||
delete queues[key];
|
||||
for (var i = 0, l = q.length; i < l; i++) {
|
||||
q[i].apply(null, arguments);
|
||||
}
|
||||
}]));
|
||||
}
|
||||
};
|
||||
memoized.memo = memo;
|
||||
memoized.unmemoized = fn;
|
||||
return memoized;
|
||||
};
|
||||
|
||||
async.unmemoize = function (fn) {
|
||||
return function () {
|
||||
return (fn.unmemoized || fn).apply(null, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
async.times = function (count, iterator, callback) {
|
||||
var counter = [];
|
||||
for (var i = 0; i < count; i++) {
|
||||
counter.push(i);
|
||||
}
|
||||
return async.map(counter, iterator, callback);
|
||||
};
|
||||
|
||||
async.timesSeries = function (count, iterator, callback) {
|
||||
var counter = [];
|
||||
for (var i = 0; i < count; i++) {
|
||||
counter.push(i);
|
||||
}
|
||||
return async.mapSeries(counter, iterator, callback);
|
||||
};
|
||||
|
||||
async.compose = function (/* functions... */) {
|
||||
var fns = Array.prototype.reverse.call(arguments);
|
||||
return function () {
|
||||
var that = this;
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var callback = args.pop();
|
||||
async.reduce(fns, args, function (newargs, fn, cb) {
|
||||
fn.apply(that, newargs.concat([function () {
|
||||
var err = arguments[0];
|
||||
var nextargs = Array.prototype.slice.call(arguments, 1);
|
||||
cb(err, nextargs);
|
||||
}]))
|
||||
},
|
||||
function (err, results) {
|
||||
callback.apply(that, [err].concat(results));
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var _applyEach = function (eachfn, fns /*args...*/) {
|
||||
var go = function () {
|
||||
var that = this;
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var callback = args.pop();
|
||||
return eachfn(fns, function (fn, cb) {
|
||||
fn.apply(that, args.concat([cb]));
|
||||
},
|
||||
callback);
|
||||
};
|
||||
if (arguments.length > 2) {
|
||||
var args = Array.prototype.slice.call(arguments, 2);
|
||||
return go.apply(this, args);
|
||||
}
|
||||
else {
|
||||
return go;
|
||||
}
|
||||
};
|
||||
async.applyEach = doParallel(_applyEach);
|
||||
async.applyEachSeries = doSeries(_applyEach);
|
||||
|
||||
async.forever = function (fn, callback) {
|
||||
function next(err) {
|
||||
if (err) {
|
||||
if (callback) {
|
||||
return callback(err);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
fn(next);
|
||||
}
|
||||
next();
|
||||
};
|
||||
|
||||
// AMD / RequireJS
|
||||
if (typeof define !== 'undefined' && define.amd) {
|
||||
define([], function () {
|
||||
return async;
|
||||
});
|
||||
}
|
||||
// Node.js
|
||||
else if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = async;
|
||||
}
|
||||
// included directly via <script> tag
|
||||
else {
|
||||
root.async = async;
|
||||
}
|
||||
|
||||
}());
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,3 @@
|
|||
node_modules
|
||||
node_modules/*
|
||||
npm_debug.log
|
|
@ -0,0 +1,4 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 0.6
|
||||
- 0.8
|
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 2011 Dominic Tarr
|
||||
|
||||
Permission is hereby granted, free of charge,
|
||||
to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify,
|
||||
merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
var inspect = require('util').inspect
|
||||
|
||||
if(!module.parent) {
|
||||
var es = require('..') //load event-stream
|
||||
es.pipe( //pipe joins streams together
|
||||
process.openStdin(), //open stdin
|
||||
es.split(), //split stream to break on newlines
|
||||
es.map(function (data, callback) {//turn this async function into a stream
|
||||
var j
|
||||
try {
|
||||
j = JSON.parse(data) //try to parse input into json
|
||||
} catch (err) {
|
||||
return callback(null, data) //if it fails just pass it anyway
|
||||
}
|
||||
callback(null, inspect(j)) //render it nicely
|
||||
}),
|
||||
process.stdout // pipe it to stdout !
|
||||
)
|
||||
}
|
||||
|
||||
// run this
|
||||
//
|
||||
// curl -sS registry.npmjs.org/event-stream | node pretty.js
|
||||
//
|
|
@ -0,0 +1,302 @@
|
|||
//filter will reemit the data if cb(err,pass) pass is truthy
|
||||
|
||||
// reduce is more tricky
|
||||
// maybe we want to group the reductions or emit progress updates occasionally
|
||||
// the most basic reduce just emits one 'data' event after it has recieved 'end'
|
||||
|
||||
var Stream = require('stream').Stream
|
||||
, es = exports
|
||||
, through = require('through')
|
||||
, from = require('from')
|
||||
, duplex = require('duplexer')
|
||||
, map = require('map-stream')
|
||||
, pause = require('pause-stream')
|
||||
, split = require('split')
|
||||
, pipeline = require('stream-combiner')
|
||||
|
||||
es.Stream = Stream //re-export Stream from core
|
||||
es.through = through
|
||||
es.from = from
|
||||
es.duplex = duplex
|
||||
es.map = map
|
||||
es.pause = pause
|
||||
es.split = split
|
||||
es.pipeline = es.connect = es.pipe = pipeline
|
||||
// merge / concat
|
||||
//
|
||||
// combine multiple streams into a single stream.
|
||||
// will emit end only once
|
||||
|
||||
es.concat = //actually this should be called concat
|
||||
es.merge = function (/*streams...*/) {
|
||||
var toMerge = [].slice.call(arguments)
|
||||
var stream = new Stream()
|
||||
var endCount = 0
|
||||
stream.writable = stream.readable = true
|
||||
|
||||
toMerge.forEach(function (e) {
|
||||
e.pipe(stream, {end: false})
|
||||
var ended = false
|
||||
e.on('end', function () {
|
||||
if(ended) return
|
||||
ended = true
|
||||
endCount ++
|
||||
if(endCount == toMerge.length)
|
||||
stream.emit('end')
|
||||
})
|
||||
})
|
||||
stream.write = function (data) {
|
||||
this.emit('data', data)
|
||||
}
|
||||
stream.destroy = function () {
|
||||
merge.forEach(function (e) {
|
||||
if(e.destroy) e.destroy()
|
||||
})
|
||||
}
|
||||
return stream
|
||||
}
|
||||
|
||||
|
||||
// writable stream, collects all events into an array
|
||||
// and calls back when 'end' occurs
|
||||
// mainly I'm using this to test the other functions
|
||||
|
||||
es.writeArray = function (done) {
|
||||
if ('function' !== typeof done)
|
||||
throw new Error('function writeArray (done): done must be function')
|
||||
|
||||
var a = new Stream ()
|
||||
, array = [], isDone = false
|
||||
a.write = function (l) {
|
||||
array.push(l)
|
||||
}
|
||||
a.end = function () {
|
||||
isDone = true
|
||||
done(null, array)
|
||||
}
|
||||
a.writable = true
|
||||
a.readable = false
|
||||
a.destroy = function () {
|
||||
a.writable = a.readable = false
|
||||
if(isDone) return
|
||||
done(new Error('destroyed before end'), array)
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
//return a Stream that reads the properties of an object
|
||||
//respecting pause() and resume()
|
||||
|
||||
es.readArray = function (array) {
|
||||
var stream = new Stream()
|
||||
, i = 0
|
||||
, paused = false
|
||||
, ended = false
|
||||
|
||||
stream.readable = true
|
||||
stream.writable = false
|
||||
|
||||
if(!Array.isArray(array))
|
||||
throw new Error('event-stream.read expects an array')
|
||||
|
||||
stream.resume = function () {
|
||||
if(ended) return
|
||||
paused = false
|
||||
var l = array.length
|
||||
while(i < l && !paused && !ended) {
|
||||
stream.emit('data', array[i++])
|
||||
}
|
||||
if(i == l && !ended)
|
||||
ended = true, stream.readable = false, stream.emit('end')
|
||||
}
|
||||
process.nextTick(stream.resume)
|
||||
stream.pause = function () {
|
||||
paused = true
|
||||
}
|
||||
stream.destroy = function () {
|
||||
ended = true
|
||||
stream.emit('close')
|
||||
}
|
||||
return stream
|
||||
}
|
||||
|
||||
//
|
||||
// readable (asyncFunction)
|
||||
// return a stream that calls an async function while the stream is not paused.
|
||||
//
|
||||
// the function must take: (count, callback) {...
|
||||
//
|
||||
|
||||
es.readable =
|
||||
function (func, continueOnError) {
|
||||
var stream = new Stream()
|
||||
, i = 0
|
||||
, paused = false
|
||||
, ended = false
|
||||
, reading = false
|
||||
|
||||
stream.readable = true
|
||||
stream.writable = false
|
||||
|
||||
if('function' !== typeof func)
|
||||
throw new Error('event-stream.readable expects async function')
|
||||
|
||||
stream.on('end', function () { ended = true })
|
||||
|
||||
function get (err, data) {
|
||||
|
||||
if(err) {
|
||||
stream.emit('error', err)
|
||||
if(!continueOnError) stream.emit('end')
|
||||
} else if (arguments.length > 1)
|
||||
stream.emit('data', data)
|
||||
|
||||
process.nextTick(function () {
|
||||
if(ended || paused || reading) return
|
||||
try {
|
||||
reading = true
|
||||
func.call(stream, i++, function () {
|
||||
reading = false
|
||||
get.apply(null, arguments)
|
||||
})
|
||||
} catch (err) {
|
||||
stream.emit('error', err)
|
||||
}
|
||||
})
|
||||
}
|
||||
stream.resume = function () {
|
||||
paused = false
|
||||
get()
|
||||
}
|
||||
process.nextTick(get)
|
||||
stream.pause = function () {
|
||||
paused = true
|
||||
}
|
||||
stream.destroy = function () {
|
||||
stream.emit('end')
|
||||
stream.emit('close')
|
||||
ended = true
|
||||
}
|
||||
return stream
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// map sync
|
||||
//
|
||||
|
||||
es.mapSync = function (sync) {
|
||||
return es.through(function write(data) {
|
||||
var mappedData = sync(data)
|
||||
if (typeof mappedData !== 'undefined')
|
||||
this.emit('data', mappedData)
|
||||
})
|
||||
}
|
||||
|
||||
//
|
||||
// log just print out what is coming through the stream, for debugging
|
||||
//
|
||||
|
||||
es.log = function (name) {
|
||||
return es.through(function (data) {
|
||||
var args = [].slice.call(arguments)
|
||||
if(name) console.error(name, data)
|
||||
else console.error(data)
|
||||
this.emit('data', data)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// child -- pipe through a child process
|
||||
//
|
||||
|
||||
es.child = function (child) {
|
||||
|
||||
return es.duplex(child.stdin, child.stdout)
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// parse
|
||||
//
|
||||
// must be used after es.split() to ensure that each chunk represents a line
|
||||
// source.pipe(es.split()).pipe(es.parse())
|
||||
|
||||
es.parse = function () {
|
||||
return es.through(function (data) {
|
||||
var obj
|
||||
try {
|
||||
if(data) //ignore empty lines
|
||||
obj = JSON.parse(data.toString())
|
||||
} catch (err) {
|
||||
return console.error(err, 'attemping to parse:', data)
|
||||
}
|
||||
//ignore lines that where only whitespace.
|
||||
if(obj !== undefined)
|
||||
this.emit('data', obj)
|
||||
})
|
||||
}
|
||||
//
|
||||
// stringify
|
||||
//
|
||||
|
||||
es.stringify = function () {
|
||||
var Buffer = require('buffer').Buffer
|
||||
return es.mapSync(function (e){
|
||||
return JSON.stringify(Buffer.isBuffer(e) ? e.toString() : e) + '\n'
|
||||
})
|
||||
}
|
||||
|
||||
//
|
||||
// replace a string within a stream.
|
||||
//
|
||||
// warn: just concatenates the string and then does str.split().join().
|
||||
// probably not optimal.
|
||||
// for smallish responses, who cares?
|
||||
// I need this for shadow-npm so it's only relatively small json files.
|
||||
|
||||
es.replace = function (from, to) {
|
||||
return es.pipeline(es.split(from), es.join(to))
|
||||
}
|
||||
|
||||
//
|
||||
// join chunks with a joiner. just like Array#join
|
||||
// also accepts a callback that is passed the chunks appended together
|
||||
// this is still supported for legacy reasons.
|
||||
//
|
||||
|
||||
es.join = function (str) {
|
||||
|
||||
//legacy api
|
||||
if('function' === typeof str)
|
||||
return es.wait(str)
|
||||
|
||||
var first = true
|
||||
return es.through(function (data) {
|
||||
if(!first)
|
||||
this.emit('data', str)
|
||||
first = false
|
||||
this.emit('data', data)
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// wait. callback when 'end' is emitted, with all chunks appended as string.
|
||||
//
|
||||
|
||||
es.wait = function (callback) {
|
||||
var body = ''
|
||||
return es.through(function (data) { body += data },
|
||||
function () {
|
||||
this.emit('data', body)
|
||||
this.emit('end')
|
||||
if(callback) callback(null, body)
|
||||
})
|
||||
}
|
||||
|
||||
es.pipeable = function () {
|
||||
throw new Error('[EVENT-STREAM] es.pipeable is deprecated')
|
||||
}
|
3
node_modules/jsftp/node_modules/event-stream/node_modules/duplexer/.npmignore
generated
vendored
Normal file
3
node_modules/jsftp/node_modules/event-stream/node_modules/duplexer/.npmignore
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
node_modules
|
||||
*.log
|
||||
*.err
|
3
node_modules/jsftp/node_modules/event-stream/node_modules/duplexer/.travis.yml
generated
vendored
Normal file
3
node_modules/jsftp/node_modules/event-stream/node_modules/duplexer/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 0.8
|
19
node_modules/jsftp/node_modules/event-stream/node_modules/duplexer/LICENCE
generated
vendored
Normal file
19
node_modules/jsftp/node_modules/event-stream/node_modules/duplexer/LICENCE
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2012 Raynos.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
4
node_modules/jsftp/node_modules/event-stream/node_modules/duplexer/Makefile
generated
vendored
Normal file
4
node_modules/jsftp/node_modules/event-stream/node_modules/duplexer/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
test:
|
||||
node test.js
|
||||
|
||||
.PHONY: test
|
36
node_modules/jsftp/node_modules/event-stream/node_modules/duplexer/README.md
generated
vendored
Normal file
36
node_modules/jsftp/node_modules/event-stream/node_modules/duplexer/README.md
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
# duplexer [![build status][1]][2]
|
||||
|
||||
Creates a duplex stream
|
||||
|
||||
Taken from [event-stream][3]
|
||||
|
||||
## duplex (writeStream, readStream)
|
||||
|
||||
Takes a writable stream and a readable stream and makes them appear as a readable writable stream.
|
||||
|
||||
It is assumed that the two streams are connected to each other in some way.
|
||||
|
||||
## Example
|
||||
|
||||
var grep = cp.exec('grep Stream')
|
||||
|
||||
duplex(grep.stdin, grep.stdout)
|
||||
|
||||
## Installation
|
||||
|
||||
`npm install duplexer`
|
||||
|
||||
## Tests
|
||||
|
||||
`make test`
|
||||
|
||||
## Contributors
|
||||
|
||||
- Dominictarr
|
||||
- Raynos
|
||||
|
||||
## MIT Licenced
|
||||
|
||||
[1]: https://secure.travis-ci.org/Raynos/duplexer.png
|
||||
[2]: http://travis-ci.org/Raynos/duplexer
|
||||
[3]: https://github.com/dominictarr/event-stream#duplex-writestream-readstream
|
77
node_modules/jsftp/node_modules/event-stream/node_modules/duplexer/index.js
generated
vendored
Normal file
77
node_modules/jsftp/node_modules/event-stream/node_modules/duplexer/index.js
generated
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
var Stream = require("stream")
|
||||
, writeMethods = ["write", "end", "destroy"]
|
||||
, readMethods = ["resume", "pause"]
|
||||
, readEvents = ["data", "close"]
|
||||
, slice = Array.prototype.slice
|
||||
|
||||
module.exports = duplex
|
||||
|
||||
function duplex(writer, reader) {
|
||||
var stream = new Stream()
|
||||
, ended = false
|
||||
|
||||
writeMethods.forEach(proxyWriter)
|
||||
|
||||
readMethods.forEach(proxyReader)
|
||||
|
||||
readEvents.forEach(proxyStream)
|
||||
|
||||
reader.on("end", handleEnd)
|
||||
|
||||
writer.on("drain", function() {
|
||||
stream.emit("drain")
|
||||
})
|
||||
|
||||
writer.on("error", reemit)
|
||||
reader.on("error", reemit)
|
||||
|
||||
stream.writable = writer.writable
|
||||
stream.readable = reader.readable
|
||||
|
||||
return stream
|
||||
|
||||
function proxyWriter(methodName) {
|
||||
stream[methodName] = method
|
||||
|
||||
function method() {
|
||||
return writer[methodName].apply(writer, arguments)
|
||||
}
|
||||
}
|
||||
|
||||
function proxyReader(methodName) {
|
||||
stream[methodName] = method
|
||||
|
||||
function method() {
|
||||
stream.emit(methodName)
|
||||
var func = reader[methodName]
|
||||
if (func) {
|
||||
return func.apply(reader, arguments)
|
||||
}
|
||||
reader.emit(methodName)
|
||||
}
|
||||
}
|
||||
|
||||
function proxyStream(methodName) {
|
||||
reader.on(methodName, reemit)
|
||||
|
||||
function reemit() {
|
||||
var args = slice.call(arguments)
|
||||
args.unshift(methodName)
|
||||
stream.emit.apply(stream, args)
|
||||
}
|
||||
}
|
||||
|
||||
function handleEnd() {
|
||||
if (ended) {
|
||||
return
|
||||
}
|
||||
ended = true
|
||||
var args = slice.call(arguments)
|
||||
args.unshift("end")
|
||||
stream.emit.apply(stream, args)
|
||||
}
|
||||
|
||||
function reemit(err) {
|
||||
stream.emit("error", err)
|
||||
}
|
||||
}
|
44
node_modules/jsftp/node_modules/event-stream/node_modules/duplexer/package.json
generated
vendored
Normal file
44
node_modules/jsftp/node_modules/event-stream/node_modules/duplexer/package.json
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"name": "duplexer",
|
||||
"version": "0.0.4",
|
||||
"description": "Creates a duplex stream",
|
||||
"keywords": [],
|
||||
"author": {
|
||||
"name": "Raynos",
|
||||
"email": "raynos2@gmail.com"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/Raynos/duplexer.git"
|
||||
},
|
||||
"main": "index",
|
||||
"homepage": "https://github.com/Raynos/duplexer",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Jake Verbaten"
|
||||
}
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/Raynos/duplexer/issues",
|
||||
"email": "raynos2@gmail.com"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"through": "~0.1.4"
|
||||
},
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT",
|
||||
"url": "http://github.com/Raynos/duplexer/raw/master/LICENSE"
|
||||
}
|
||||
],
|
||||
"scripts": {
|
||||
"test": "make test"
|
||||
},
|
||||
"readme": "# duplexer [![build status][1]][2]\n\nCreates a duplex stream\n\nTaken from [event-stream][3]\n\n## duplex (writeStream, readStream)\n\nTakes a writable stream and a readable stream and makes them appear as a readable writable stream.\n\nIt is assumed that the two streams are connected to each other in some way.\n\n## Example\n\n var grep = cp.exec('grep Stream')\n\n duplex(grep.stdin, grep.stdout)\n\n## Installation\n\n`npm install duplexer`\n\n## Tests\n\n`make test`\n\n## Contributors\n\n - Dominictarr\n - Raynos\n\n## MIT Licenced\n\n [1]: https://secure.travis-ci.org/Raynos/duplexer.png\n [2]: http://travis-ci.org/Raynos/duplexer\n [3]: https://github.com/dominictarr/event-stream#duplex-writestream-readstream",
|
||||
"_id": "duplexer@0.0.4",
|
||||
"dist": {
|
||||
"shasum": "49e7655791cdb887f4ce1616756bbb5f65d96157"
|
||||
},
|
||||
"_from": "duplexer@~0.0.2"
|
||||
}
|
27
node_modules/jsftp/node_modules/event-stream/node_modules/duplexer/test.js
generated
vendored
Normal file
27
node_modules/jsftp/node_modules/event-stream/node_modules/duplexer/test.js
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
var duplex = require("./index")
|
||||
, assert = require("assert")
|
||||
, through = require("through")
|
||||
|
||||
var readable = through()
|
||||
, writable = through(write)
|
||||
, written = 0
|
||||
, data = 0
|
||||
|
||||
var stream = duplex(writable, readable)
|
||||
|
||||
function write() {
|
||||
written++
|
||||
}
|
||||
|
||||
stream.on("data", ondata)
|
||||
|
||||
function ondata() {
|
||||
data++
|
||||
}
|
||||
|
||||
stream.write()
|
||||
readable.emit("data")
|
||||
|
||||
assert.equal(written, 1)
|
||||
assert.equal(data, 1)
|
||||
console.log("DONE")
|
1
node_modules/jsftp/node_modules/event-stream/node_modules/from/.npmignore
generated
vendored
Normal file
1
node_modules/jsftp/node_modules/event-stream/node_modules/from/.npmignore
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
node_modules
|
15
node_modules/jsftp/node_modules/event-stream/node_modules/from/LICENSE.APACHE2
generated
vendored
Normal file
15
node_modules/jsftp/node_modules/event-stream/node_modules/from/LICENSE.APACHE2
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
Apache License, Version 2.0
|
||||
|
||||
Copyright (c) 2011 Dominic Tarr
|
||||
|
||||
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.
|
24
node_modules/jsftp/node_modules/event-stream/node_modules/from/LICENSE.MIT
generated
vendored
Normal file
24
node_modules/jsftp/node_modules/event-stream/node_modules/from/LICENSE.MIT
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
The MIT License
|
||||
|
||||
Copyright (c) 2011 Dominic Tarr
|
||||
|
||||
Permission is hereby granted, free of charge,
|
||||
to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify,
|
||||
merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
68
node_modules/jsftp/node_modules/event-stream/node_modules/from/index.js
generated
vendored
Normal file
68
node_modules/jsftp/node_modules/event-stream/node_modules/from/index.js
generated
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var Stream = require('stream')
|
||||
|
||||
// from
|
||||
//
|
||||
// a stream that reads from an source.
|
||||
// source may be an array, or a function.
|
||||
// from handles pause behaviour for you.
|
||||
|
||||
module.exports =
|
||||
function from (source) {
|
||||
if(Array.isArray(source)) {
|
||||
source = source.slice()
|
||||
return from (function (i) {
|
||||
if(source.length)
|
||||
this.emit('data', source.shift())
|
||||
else
|
||||
this.emit('end')
|
||||
return true
|
||||
})
|
||||
}
|
||||
var s = new Stream(), i = 0
|
||||
s.ended = false
|
||||
s.started = false
|
||||
s.readable = true
|
||||
s.writable = false
|
||||
s.paused = false
|
||||
s.ended = false
|
||||
s.pause = function () {
|
||||
s.started = true
|
||||
s.paused = true
|
||||
}
|
||||
function next () {
|
||||
s.started = true
|
||||
if(s.ended) return
|
||||
while(!s.ended && !s.paused && source.call(s, i++, function () {
|
||||
if(!s.ended && !s.paused)
|
||||
next()
|
||||
}))
|
||||
;
|
||||
}
|
||||
s.resume = function () {
|
||||
s.started = true
|
||||
s.paused = false
|
||||
next()
|
||||
}
|
||||
s.on('end', function () {
|
||||
s.ended = true
|
||||
s.readable = false
|
||||
process.nextTick(s.destroy)
|
||||
})
|
||||
s.destroy = function () {
|
||||
s.ended = true
|
||||
s.emit('close')
|
||||
}
|
||||
/*
|
||||
by default, the stream will start emitting at nextTick
|
||||
if you want, you can pause it, after pipeing.
|
||||
you can also resume before next tick, and that will also
|
||||
work.
|
||||
*/
|
||||
process.nextTick(function () {
|
||||
if(!s.started) s.resume()
|
||||
})
|
||||
return s
|
||||
}
|
36
node_modules/jsftp/node_modules/event-stream/node_modules/from/package.json
generated
vendored
Normal file
36
node_modules/jsftp/node_modules/event-stream/node_modules/from/package.json
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"name": "from",
|
||||
"version": "0.1.3",
|
||||
"description": "Easy way to make a Readable Stream",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "asynct test/*.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/dominictarr/from.git"
|
||||
},
|
||||
"keywords": [
|
||||
"stream",
|
||||
"streams",
|
||||
"readable",
|
||||
"easy"
|
||||
],
|
||||
"devDependencies": {
|
||||
"asynct": "1",
|
||||
"stream-spec": "0",
|
||||
"assertions": "~2.3.0"
|
||||
},
|
||||
"author": {
|
||||
"name": "Dominic Tarr",
|
||||
"email": "dominic.tarr@gmail.com",
|
||||
"url": "dominictarr.com"
|
||||
},
|
||||
"license": "MIT",
|
||||
"readme": "# from\n\nAn easy way to create a `readable Stream`.\n\n## from(function getChunk(count, next))\n\nfrom takes a `getChunk` function and returns a stream. \n\n`getChunk` is called again and again, after each time the user calls `next()`, \nuntil the user emits `'end'`\n\nif `pause()` is called, the `getChunk` won't be called again untill `resume()` is called.\n\n\n```js\nvar from = require('from')\n\nvar stream = \n from(function getChunk(count, next) {\n //do some sort of data\n this.emit('data', whatever)\n \n if(itsOver)\n this.emit('end')\n\n //ready to handle the next chunk\n next()\n //or, if it's sync:\n return true \n })\n```\n\n## from(array)\n\nfrom also takes an `Array` whose elements it emits one after another.\n\n## License\nMIT / Apache2\n",
|
||||
"_id": "from@0.1.3",
|
||||
"dist": {
|
||||
"shasum": "0ac5c9c9018c3f249f72e92396f3e5f25aa6fdbd"
|
||||
},
|
||||
"_from": "from@~0"
|
||||
}
|
38
node_modules/jsftp/node_modules/event-stream/node_modules/from/readme.markdown
generated
vendored
Normal file
38
node_modules/jsftp/node_modules/event-stream/node_modules/from/readme.markdown
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
# from
|
||||
|
||||
An easy way to create a `readable Stream`.
|
||||
|
||||
## from(function getChunk(count, next))
|
||||
|
||||
from takes a `getChunk` function and returns a stream.
|
||||
|
||||
`getChunk` is called again and again, after each time the user calls `next()`,
|
||||
until the user emits `'end'`
|
||||
|
||||
if `pause()` is called, the `getChunk` won't be called again untill `resume()` is called.
|
||||
|
||||
|
||||
```js
|
||||
var from = require('from')
|
||||
|
||||
var stream =
|
||||
from(function getChunk(count, next) {
|
||||
//do some sort of data
|
||||
this.emit('data', whatever)
|
||||
|
||||
if(itsOver)
|
||||
this.emit('end')
|
||||
|
||||
//ready to handle the next chunk
|
||||
next()
|
||||
//or, if it's sync:
|
||||
return true
|
||||
})
|
||||
```
|
||||
|
||||
## from(array)
|
||||
|
||||
from also takes an `Array` whose elements it emits one after another.
|
||||
|
||||
## License
|
||||
MIT / Apache2
|
141
node_modules/jsftp/node_modules/event-stream/node_modules/from/test/index.js
generated
vendored
Normal file
141
node_modules/jsftp/node_modules/event-stream/node_modules/from/test/index.js
generated
vendored
Normal file
|
@ -0,0 +1,141 @@
|
|||
var from = require('..')
|
||||
var spec = require('stream-spec')
|
||||
var a = require('assertions')
|
||||
|
||||
function read(stream, callback) {
|
||||
var actual = []
|
||||
stream.on('data', function (data) {
|
||||
actual.push(data)
|
||||
})
|
||||
stream.once('end', function () {
|
||||
callback(null, actual)
|
||||
})
|
||||
stream.once('error', function (err) {
|
||||
callback(err)
|
||||
})
|
||||
}
|
||||
|
||||
function pause(stream) {
|
||||
stream.on('data', function () {
|
||||
if(Math.random() > 0.1) return
|
||||
stream.pause()
|
||||
process.nextTick(function () {
|
||||
stream.resume()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
exports['inc'] = function (test) {
|
||||
|
||||
var fs = from(function (i) {
|
||||
this.emit('data', i)
|
||||
if(i >= 99)
|
||||
return this.emit('end')
|
||||
return true
|
||||
})
|
||||
|
||||
spec(fs).readable().validateOnExit()
|
||||
|
||||
read(fs, function (err, arr) {
|
||||
test.equal(arr.length, 100)
|
||||
test.done()
|
||||
})
|
||||
}
|
||||
|
||||
exports['simple'] = function (test) {
|
||||
|
||||
var l = 1000
|
||||
, expected = []
|
||||
|
||||
while(l--) expected.push(l * Math.random())
|
||||
|
||||
var t = from(expected.slice())
|
||||
|
||||
spec(t)
|
||||
.readable()
|
||||
.pausable({strict: true})
|
||||
.validateOnExit()
|
||||
|
||||
read(t, function (err, actual) {
|
||||
if(err) test.error(err) //fail
|
||||
a.deepEqual(actual, expected)
|
||||
test.done()
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
exports['simple pausable'] = function (test) {
|
||||
|
||||
var l = 1000
|
||||
, expected = []
|
||||
|
||||
while(l--) expected.push(l * Math.random())
|
||||
|
||||
var t = from(expected.slice())
|
||||
|
||||
spec(t)
|
||||
.readable()
|
||||
.pausable({strict: true})
|
||||
.validateOnExit()
|
||||
|
||||
pause(t)
|
||||
|
||||
read(t, function (err, actual) {
|
||||
if(err) test.error(err) //fail
|
||||
a.deepEqual(actual, expected)
|
||||
test.done()
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
exports['simple (not strictly pausable) setTimeout'] = function (test) {
|
||||
|
||||
var l = 10
|
||||
, expected = []
|
||||
while(l--) expected.push(l * Math.random())
|
||||
|
||||
|
||||
var _expected = expected.slice()
|
||||
var t = from(function (i, n) {
|
||||
var self = this
|
||||
setTimeout(function () {
|
||||
if(_expected.length)
|
||||
self.emit('data', _expected.shift())
|
||||
else
|
||||
self.emit('end')
|
||||
n()
|
||||
}, 3)
|
||||
})
|
||||
|
||||
/*
|
||||
using from in this way will not be strictly pausable.
|
||||
it could be extended to buffer outputs, but I think a better
|
||||
way would be to use a PauseStream that implements strict pause.
|
||||
*/
|
||||
|
||||
spec(t)
|
||||
.readable()
|
||||
.pausable({strict: false })
|
||||
.validateOnExit()
|
||||
|
||||
//pause(t)
|
||||
var paused = false
|
||||
var i = setInterval(function () {
|
||||
if(!paused) t.pause()
|
||||
else t.resume()
|
||||
paused = !paused
|
||||
}, 2)
|
||||
|
||||
t.on('end', function () {
|
||||
clearInterval(i)
|
||||
})
|
||||
|
||||
read(t, function (err, actual) {
|
||||
if(err) test.error(err) //fail
|
||||
a.deepEqual(actual, expected)
|
||||
test.done()
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
3
node_modules/jsftp/node_modules/event-stream/node_modules/map-stream/.npmignore
generated
vendored
Normal file
3
node_modules/jsftp/node_modules/event-stream/node_modules/map-stream/.npmignore
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
node_modules
|
||||
node_modules/*
|
||||
npm_debug.log
|
4
node_modules/jsftp/node_modules/event-stream/node_modules/map-stream/.travis.yml
generated
vendored
Normal file
4
node_modules/jsftp/node_modules/event-stream/node_modules/map-stream/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 0.6
|
||||
- 0.8
|
22
node_modules/jsftp/node_modules/event-stream/node_modules/map-stream/LICENCE
generated
vendored
Normal file
22
node_modules/jsftp/node_modules/event-stream/node_modules/map-stream/LICENCE
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 2011 Dominic Tarr
|
||||
|
||||
Permission is hereby granted, free of charge,
|
||||
to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify,
|
||||
merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
26
node_modules/jsftp/node_modules/event-stream/node_modules/map-stream/examples/pretty.js
generated
vendored
Normal file
26
node_modules/jsftp/node_modules/event-stream/node_modules/map-stream/examples/pretty.js
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
|
||||
var inspect = require('util').inspect
|
||||
|
||||
if(!module.parent) {
|
||||
var map = require('..') //load map-stream
|
||||
var es = require('event-stream') //load event-stream
|
||||
es.pipe( //pipe joins streams together
|
||||
process.openStdin(), //open stdin
|
||||
es.split(), //split stream to break on newlines
|
||||
map(function (data, callback) { //turn this async function into a stream
|
||||
var j
|
||||
try {
|
||||
j = JSON.parse(data) //try to parse input into json
|
||||
} catch (err) {
|
||||
return callback(null, data) //if it fails just pass it anyway
|
||||
}
|
||||
callback(null, inspect(j)) //render it nicely
|
||||
}),
|
||||
process.stdout // pipe it to stdout !
|
||||
)
|
||||
}
|
||||
|
||||
// run this
|
||||
//
|
||||
// curl -sS registry.npmjs.org/event-stream | node pretty.js
|
||||
//
|
105
node_modules/jsftp/node_modules/event-stream/node_modules/map-stream/index.js
generated
vendored
Normal file
105
node_modules/jsftp/node_modules/event-stream/node_modules/map-stream/index.js
generated
vendored
Normal file
|
@ -0,0 +1,105 @@
|
|||
//filter will reemit the data if cb(err,pass) pass is truthy
|
||||
|
||||
// reduce is more tricky
|
||||
// maybe we want to group the reductions or emit progress updates occasionally
|
||||
// the most basic reduce just emits one 'data' event after it has recieved 'end'
|
||||
|
||||
|
||||
var Stream = require('stream').Stream
|
||||
|
||||
|
||||
//create an event stream and apply function to each .write
|
||||
//emitting each response as data
|
||||
//unless it's an empty callback
|
||||
|
||||
module.exports = function (mapper) {
|
||||
var stream = new Stream()
|
||||
, inputs = 0
|
||||
, outputs = 0
|
||||
, ended = false
|
||||
, paused = false
|
||||
, destroyed = false
|
||||
|
||||
stream.writable = true
|
||||
stream.readable = true
|
||||
|
||||
stream.write = function () {
|
||||
if(ended) throw new Error('map stream is not writable')
|
||||
inputs ++
|
||||
var args = [].slice.call(arguments)
|
||||
, r
|
||||
, inNext = false
|
||||
//pipe only allows one argument. so, do not
|
||||
function next (err) {
|
||||
if(destroyed) return
|
||||
inNext = true
|
||||
outputs ++
|
||||
var args = [].slice.call(arguments)
|
||||
if(err) {
|
||||
args.unshift('error')
|
||||
return inNext = false, stream.emit.apply(stream, args)
|
||||
}
|
||||
args.shift() //drop err
|
||||
if (args.length) {
|
||||
args.unshift('data')
|
||||
r = stream.emit.apply(stream, args)
|
||||
}
|
||||
if(inputs == outputs) {
|
||||
if(paused) paused = false, stream.emit('drain') //written all the incoming events
|
||||
if(ended) end()
|
||||
}
|
||||
inNext = false
|
||||
}
|
||||
args.push(next)
|
||||
|
||||
try {
|
||||
//catch sync errors and handle them like async errors
|
||||
var written = mapper.apply(null, args)
|
||||
paused = (written === false)
|
||||
return !paused
|
||||
} catch (err) {
|
||||
//if the callback has been called syncronously, and the error
|
||||
//has occured in an listener, throw it again.
|
||||
if(inNext)
|
||||
throw err
|
||||
next(err)
|
||||
return !paused
|
||||
}
|
||||
}
|
||||
|
||||
function end (data) {
|
||||
//if end was called with args, write it,
|
||||
ended = true //write will emit 'end' if ended is true
|
||||
stream.writable = false
|
||||
if(data !== undefined)
|
||||
return stream.write(data)
|
||||
else if (inputs == outputs) //wait for processing
|
||||
stream.readable = false, stream.emit('end'), stream.destroy()
|
||||
}
|
||||
|
||||
stream.end = function (data) {
|
||||
if(ended) return
|
||||
end()
|
||||
}
|
||||
|
||||
stream.destroy = function () {
|
||||
ended = destroyed = true
|
||||
stream.writable = stream.readable = paused = false
|
||||
process.nextTick(function () {
|
||||
stream.emit('close')
|
||||
})
|
||||
}
|
||||
stream.pause = function () {
|
||||
paused = true
|
||||
}
|
||||
|
||||
stream.resume = function () {
|
||||
paused = false
|
||||
}
|
||||
|
||||
return stream
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
33
node_modules/jsftp/node_modules/event-stream/node_modules/map-stream/package.json
generated
vendored
Normal file
33
node_modules/jsftp/node_modules/event-stream/node_modules/map-stream/package.json
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"name": "map-stream",
|
||||
"version": "0.0.2",
|
||||
"description": "construct pipes of streams of events",
|
||||
"homepage": "http://github.com/dominictarr/map-stream",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/dominictarr/map-stream.git"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"asynct": "*",
|
||||
"it-is": "1",
|
||||
"ubelt": "~2.9",
|
||||
"stream-spec": "~0.2",
|
||||
"event-stream": "~2.1",
|
||||
"from": "0.0.2"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "asynct test/"
|
||||
},
|
||||
"author": {
|
||||
"name": "Dominic Tarr",
|
||||
"email": "dominic.tarr@gmail.com",
|
||||
"url": "http://dominictarr.com"
|
||||
},
|
||||
"readme": "# MapStream\n\nRefactored out of [event-stream](https://github.com/dominictarr/event-stream)\n\n##map (asyncFunction)\n\nCreate a through stream from an asyncronous function. \n\n``` js\nvar map = require('map-stream')\n\nmap(function (data, callback) {\n //transform data\n // ...\n callback(null, data)\n})\n\n```\n\nEach map MUST call the callback. It may callback with data, with an error or with no arguments, \n\n * `callback()` drop this data. \n this makes the map work like `filter`, \n note:`callback(null,null)` is not the same, and will emit `null`\n\n * `callback(null, newData)` turn data into newData\n \n * `callback(error)` emit an error for this item.\n\n>Note: if a callback is not called, `map` will think that it is still being processed, \n>every call must be answered or the stream will not know when to end. \n>\n>Also, if the callback is called more than once, every call but the first will be ignored.\n\n\n",
|
||||
"_id": "map-stream@0.0.2",
|
||||
"dist": {
|
||||
"shasum": "8c7fc337e11ea95e1e6edc5b18b7e4a2944e2f0f"
|
||||
},
|
||||
"_from": "map-stream@0.0.2"
|
||||
}
|
35
node_modules/jsftp/node_modules/event-stream/node_modules/map-stream/readme.markdown
generated
vendored
Normal file
35
node_modules/jsftp/node_modules/event-stream/node_modules/map-stream/readme.markdown
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
# MapStream
|
||||
|
||||
Refactored out of [event-stream](https://github.com/dominictarr/event-stream)
|
||||
|
||||
##map (asyncFunction)
|
||||
|
||||
Create a through stream from an asyncronous function.
|
||||
|
||||
``` js
|
||||
var map = require('map-stream')
|
||||
|
||||
map(function (data, callback) {
|
||||
//transform data
|
||||
// ...
|
||||
callback(null, data)
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
Each map MUST call the callback. It may callback with data, with an error or with no arguments,
|
||||
|
||||
* `callback()` drop this data.
|
||||
this makes the map work like `filter`,
|
||||
note:`callback(null,null)` is not the same, and will emit `null`
|
||||
|
||||
* `callback(null, newData)` turn data into newData
|
||||
|
||||
* `callback(error)` emit an error for this item.
|
||||
|
||||
>Note: if a callback is not called, `map` will think that it is still being processed,
|
||||
>every call must be answered or the stream will not know when to end.
|
||||
>
|
||||
>Also, if the callback is called more than once, every call but the first will be ignored.
|
||||
|
||||
|
270
node_modules/jsftp/node_modules/event-stream/node_modules/map-stream/test/simple-map.asynct.js
generated
vendored
Normal file
270
node_modules/jsftp/node_modules/event-stream/node_modules/map-stream/test/simple-map.asynct.js
generated
vendored
Normal file
|
@ -0,0 +1,270 @@
|
|||
'use strict';
|
||||
|
||||
var map = require('../')
|
||||
, it = require('it-is')
|
||||
, u = require('ubelt')
|
||||
, spec = require('stream-spec')
|
||||
, from = require('from')
|
||||
, Stream = require('stream')
|
||||
, es = require('event-stream')
|
||||
|
||||
//REFACTOR THIS TEST TO USE es.readArray and es.writeArray
|
||||
|
||||
function writeArray(array, stream) {
|
||||
|
||||
array.forEach( function (j) {
|
||||
stream.write(j)
|
||||
})
|
||||
stream.end()
|
||||
|
||||
}
|
||||
|
||||
function readStream(stream, done) {
|
||||
|
||||
var array = []
|
||||
stream.on('data', function (data) {
|
||||
array.push(data)
|
||||
})
|
||||
stream.on('error', done)
|
||||
stream.on('end', function (data) {
|
||||
done(null, array)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
//call sink on each write,
|
||||
//and complete when finished.
|
||||
|
||||
function pauseStream (prob, delay) {
|
||||
var pauseIf = (
|
||||
'number' == typeof prob
|
||||
? function () {
|
||||
return Math.random() < prob
|
||||
}
|
||||
: 'function' == typeof prob
|
||||
? prob
|
||||
: 0.1
|
||||
)
|
||||
var delayer = (
|
||||
!delay
|
||||
? process.nextTick
|
||||
: 'number' == typeof delay
|
||||
? function (next) { setTimeout(next, delay) }
|
||||
: delay
|
||||
)
|
||||
|
||||
return es.through(function (data) {
|
||||
if(!this.paused && pauseIf()) {
|
||||
console.log('PAUSE STREAM PAUSING')
|
||||
this.pause()
|
||||
var self = this
|
||||
delayer(function () {
|
||||
console.log('PAUSE STREAM RESUMING')
|
||||
self.resume()
|
||||
})
|
||||
}
|
||||
console.log("emit ('data', " + data + ')')
|
||||
this.emit('data', data)
|
||||
})
|
||||
}
|
||||
|
||||
exports ['simple map applied to a stream'] = function (test) {
|
||||
|
||||
var input = [1,2,3,7,5,3,1,9,0,2,4,6]
|
||||
//create event stream from
|
||||
|
||||
var doubler = map(function (data, cb) {
|
||||
cb(null, data * 2)
|
||||
})
|
||||
|
||||
spec(doubler).through().validateOnExit()
|
||||
|
||||
//a map is only a middle man, so it is both readable and writable
|
||||
|
||||
it(doubler).has({
|
||||
readable: true,
|
||||
writable: true,
|
||||
})
|
||||
|
||||
readStream(doubler, function (err, output) {
|
||||
it(output).deepEqual(input.map(function (j) {
|
||||
return j * 2
|
||||
}))
|
||||
// process.nextTick(x.validate)
|
||||
test.done()
|
||||
})
|
||||
|
||||
writeArray(input, doubler)
|
||||
|
||||
}
|
||||
|
||||
exports['pipe two maps together'] = function (test) {
|
||||
|
||||
var input = [1,2,3,7,5,3,1,9,0,2,4,6]
|
||||
//create event stream from
|
||||
function dd (data, cb) {
|
||||
cb(null, data * 2)
|
||||
}
|
||||
var doubler1 = map(dd), doubler2 = map(dd)
|
||||
|
||||
doubler1.pipe(doubler2)
|
||||
|
||||
spec(doubler1).through().validateOnExit()
|
||||
spec(doubler2).through().validateOnExit()
|
||||
|
||||
readStream(doubler2, function (err, output) {
|
||||
it(output).deepEqual(input.map(function (j) {
|
||||
return j * 4
|
||||
}))
|
||||
test.done()
|
||||
})
|
||||
|
||||
writeArray(input, doubler1)
|
||||
|
||||
}
|
||||
|
||||
//next:
|
||||
//
|
||||
// test pause, resume and drian.
|
||||
//
|
||||
|
||||
// then make a pipe joiner:
|
||||
//
|
||||
// plumber (evStr1, evStr2, evStr3, evStr4, evStr5)
|
||||
//
|
||||
// will return a single stream that write goes to the first
|
||||
|
||||
exports ['map will not call end until the callback'] = function (test) {
|
||||
|
||||
var ticker = map(function (data, cb) {
|
||||
process.nextTick(function () {
|
||||
cb(null, data * 2)
|
||||
})
|
||||
})
|
||||
|
||||
spec(ticker).through().validateOnExit()
|
||||
|
||||
ticker.write('x')
|
||||
ticker.end()
|
||||
|
||||
ticker.on('end', function () {
|
||||
test.done()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
exports ['emit error thrown'] = function (test) {
|
||||
|
||||
var err = new Error('INTENSIONAL ERROR')
|
||||
, mapper =
|
||||
map(function () {
|
||||
throw err
|
||||
})
|
||||
|
||||
mapper.on('error', function (_err) {
|
||||
it(_err).equal(err)
|
||||
test.done()
|
||||
})
|
||||
|
||||
mapper.write('hello')
|
||||
|
||||
}
|
||||
|
||||
exports ['emit error calledback'] = function (test) {
|
||||
|
||||
var err = new Error('INTENSIONAL ERROR')
|
||||
, mapper =
|
||||
map(function (data, callback) {
|
||||
callback(err)
|
||||
})
|
||||
|
||||
mapper.on('error', function (_err) {
|
||||
it(_err).equal(err)
|
||||
test.done()
|
||||
})
|
||||
|
||||
mapper.write('hello')
|
||||
|
||||
}
|
||||
|
||||
exports ['do not emit drain if not paused'] = function (test) {
|
||||
|
||||
var maps = map(function (data, callback) {
|
||||
u.delay(callback)(null, 1)
|
||||
return true
|
||||
})
|
||||
|
||||
spec(maps).through().pausable().validateOnExit()
|
||||
|
||||
maps.on('drain', function () {
|
||||
it(false).ok('should not emit drain unless the stream is paused')
|
||||
})
|
||||
|
||||
it(maps.write('hello')).equal(true)
|
||||
it(maps.write('hello')).equal(true)
|
||||
it(maps.write('hello')).equal(true)
|
||||
setTimeout(function () {maps.end()},10)
|
||||
maps.on('end', test.done)
|
||||
}
|
||||
|
||||
exports ['emits drain if paused, when all '] = function (test) {
|
||||
var active = 0
|
||||
var drained = false
|
||||
var maps = map(function (data, callback) {
|
||||
active ++
|
||||
u.delay(function () {
|
||||
active --
|
||||
callback(null, 1)
|
||||
})()
|
||||
console.log('WRITE', false)
|
||||
return false
|
||||
})
|
||||
|
||||
spec(maps).through().validateOnExit()
|
||||
|
||||
maps.on('drain', function () {
|
||||
drained = true
|
||||
it(active).equal(0, 'should emit drain when all maps are done')
|
||||
})
|
||||
|
||||
it(maps.write('hello')).equal(false)
|
||||
it(maps.write('hello')).equal(false)
|
||||
it(maps.write('hello')).equal(false)
|
||||
|
||||
process.nextTick(function () {maps.end()},10)
|
||||
|
||||
maps.on('end', function () {
|
||||
console.log('end')
|
||||
it(drained).ok('shoud have emitted drain before end')
|
||||
test.done()
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
exports ['map applied to a stream with filtering'] = function (test) {
|
||||
|
||||
var input = [1,2,3,7,5,3,1,9,0,2,4,6]
|
||||
|
||||
var doubler = map(function (data, callback) {
|
||||
if (data % 2)
|
||||
callback(null, data * 2)
|
||||
else
|
||||
callback()
|
||||
})
|
||||
|
||||
readStream(doubler, function (err, output) {
|
||||
it(output).deepEqual(input.filter(function (j) {
|
||||
return j % 2
|
||||
}).map(function (j) {
|
||||
return j * 2
|
||||
}))
|
||||
test.done()
|
||||
})
|
||||
|
||||
spec(doubler).through().validateOnExit()
|
||||
|
||||
writeArray(input, doubler)
|
||||
|
||||
}
|
||||
|
||||
|
3
node_modules/jsftp/node_modules/event-stream/node_modules/pause-stream/.npmignore
generated
vendored
Normal file
3
node_modules/jsftp/node_modules/event-stream/node_modules/pause-stream/.npmignore
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
node_modules
|
||||
node_modules/*
|
||||
npm_debug.log
|
3
node_modules/jsftp/node_modules/event-stream/node_modules/pause-stream/index.js
generated
vendored
Normal file
3
node_modules/jsftp/node_modules/event-stream/node_modules/pause-stream/index.js
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
//through@2 handles this by default!
|
||||
module.exports = require('through')
|
||||
|
45
node_modules/jsftp/node_modules/event-stream/node_modules/pause-stream/package.json
generated
vendored
Normal file
45
node_modules/jsftp/node_modules/event-stream/node_modules/pause-stream/package.json
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"name": "pause-stream",
|
||||
"version": "0.0.10",
|
||||
"description": "a ThroughStream that strictly buffers all readable events when paused.",
|
||||
"main": "index.js",
|
||||
"directories": {
|
||||
"test": "test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"stream-tester": "0.0.2",
|
||||
"stream-spec": "~0.2.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node test/index.js && node test/pause-end.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/dominictarr/pause-stream.git"
|
||||
},
|
||||
"keywords": [
|
||||
"stream",
|
||||
"pipe",
|
||||
"pause",
|
||||
"drain",
|
||||
"buffer"
|
||||
],
|
||||
"author": {
|
||||
"name": "Dominic Tarr",
|
||||
"email": "dominic.tarr@gmail.com",
|
||||
"url": "dominictarr.com"
|
||||
},
|
||||
"license": [
|
||||
"MIT",
|
||||
"Apache2"
|
||||
],
|
||||
"dependencies": {
|
||||
"through": "~2.3"
|
||||
},
|
||||
"readme": "# PauseStream\n\nThis is a `Stream` that will strictly buffer when paused.\nConnect it to anything you need buffered.\n\n``` js\n var ps = require('pause-stream')();\n\n badlyBehavedStream.pipe(ps.pause())\n\n aLittleLater(function (err, data) {\n ps.pipe(createAnotherStream(data))\n ps.resume()\n })\n```\n\n`PauseStream` will buffer whenever paused.\nit will buffer when yau have called `pause` manually.\nbut also when it's downstream `dest.write()===false`.\nit will attempt to drain the buffer when you call resume\nor the downstream emits `'drain'`\n\n`PauseStream` is tested using [stream-spec](https://github.com/dominictarr/stream-spec)\nand [stream-tester](https://github.com/dominictarr/stream-tester)\n\nThis is now the default case of \n[through](https://github.com/dominictarr/through)\n\nhttps://github.com/dominictarr/pause-stream/commit/4a6fe3dc2c11091b1efbfde912e0473719ed9cc0\n",
|
||||
"_id": "pause-stream@0.0.10",
|
||||
"dist": {
|
||||
"shasum": "0b28365a705bb18fecd89d4722e11275c109eb66"
|
||||
},
|
||||
"_from": "pause-stream@0.0.10"
|
||||
}
|
29
node_modules/jsftp/node_modules/event-stream/node_modules/pause-stream/readme.markdown
generated
vendored
Normal file
29
node_modules/jsftp/node_modules/event-stream/node_modules/pause-stream/readme.markdown
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
# PauseStream
|
||||
|
||||
This is a `Stream` that will strictly buffer when paused.
|
||||
Connect it to anything you need buffered.
|
||||
|
||||
``` js
|
||||
var ps = require('pause-stream')();
|
||||
|
||||
badlyBehavedStream.pipe(ps.pause())
|
||||
|
||||
aLittleLater(function (err, data) {
|
||||
ps.pipe(createAnotherStream(data))
|
||||
ps.resume()
|
||||
})
|
||||
```
|
||||
|
||||
`PauseStream` will buffer whenever paused.
|
||||
it will buffer when yau have called `pause` manually.
|
||||
but also when it's downstream `dest.write()===false`.
|
||||
it will attempt to drain the buffer when you call resume
|
||||
or the downstream emits `'drain'`
|
||||
|
||||
`PauseStream` is tested using [stream-spec](https://github.com/dominictarr/stream-spec)
|
||||
and [stream-tester](https://github.com/dominictarr/stream-tester)
|
||||
|
||||
This is now the default case of
|
||||
[through](https://github.com/dominictarr/through)
|
||||
|
||||
https://github.com/dominictarr/pause-stream/commit/4a6fe3dc2c11091b1efbfde912e0473719ed9cc0
|
17
node_modules/jsftp/node_modules/event-stream/node_modules/pause-stream/test/index.js
generated
vendored
Normal file
17
node_modules/jsftp/node_modules/event-stream/node_modules/pause-stream/test/index.js
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
var spec = require('stream-spec')
|
||||
var tester = require('stream-tester')
|
||||
var ps = require('..')()
|
||||
|
||||
spec(ps)
|
||||
.through({strict: false})
|
||||
.validateOnExit()
|
||||
|
||||
var master = tester.createConsistent
|
||||
|
||||
tester.createRandomStream(1000) //1k random numbers
|
||||
.pipe(master = tester.createConsistentStream())
|
||||
.pipe(tester.createUnpauseStream())
|
||||
.pipe(ps)
|
||||
.pipe(tester.createPauseStream())
|
||||
.pipe(master.createSlave())
|
||||
|
33
node_modules/jsftp/node_modules/event-stream/node_modules/pause-stream/test/pause-end.js
generated
vendored
Normal file
33
node_modules/jsftp/node_modules/event-stream/node_modules/pause-stream/test/pause-end.js
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
|
||||
var pause = require('..')
|
||||
var assert = require('assert')
|
||||
|
||||
var ps = pause()
|
||||
var read = [], ended = false
|
||||
|
||||
ps.on('data', function (i) {
|
||||
read.push(i)
|
||||
})
|
||||
|
||||
ps.on('end', function () {
|
||||
ended = true
|
||||
})
|
||||
|
||||
assert.deepEqual(read, [])
|
||||
|
||||
ps.write(0)
|
||||
ps.write(1)
|
||||
ps.write(2)
|
||||
|
||||
assert.deepEqual(read, [0, 1, 2])
|
||||
|
||||
ps.pause()
|
||||
|
||||
assert.deepEqual(read, [0, 1, 2])
|
||||
|
||||
ps.end()
|
||||
assert.equal(ended, false)
|
||||
ps.resume()
|
||||
assert.equal(ended, true)
|
||||
|
||||
|
3
node_modules/jsftp/node_modules/event-stream/node_modules/split/.npmignore
generated
vendored
Normal file
3
node_modules/jsftp/node_modules/event-stream/node_modules/split/.npmignore
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
node_modules
|
||||
node_modules/*
|
||||
npm_debug.log
|
4
node_modules/jsftp/node_modules/event-stream/node_modules/split/.travis.yml
generated
vendored
Normal file
4
node_modules/jsftp/node_modules/event-stream/node_modules/split/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 0.8
|
||||
- "0.10"
|
22
node_modules/jsftp/node_modules/event-stream/node_modules/split/LICENCE
generated
vendored
Normal file
22
node_modules/jsftp/node_modules/event-stream/node_modules/split/LICENCE
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 2011 Dominic Tarr
|
||||
|
||||
Permission is hereby granted, free of charge,
|
||||
to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify,
|
||||
merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
26
node_modules/jsftp/node_modules/event-stream/node_modules/split/examples/pretty.js
generated
vendored
Normal file
26
node_modules/jsftp/node_modules/event-stream/node_modules/split/examples/pretty.js
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
|
||||
var inspect = require('util').inspect
|
||||
var es = require('event-stream') //load event-stream
|
||||
var split = require('../')
|
||||
|
||||
if(!module.parent) {
|
||||
es.pipe( //pipe joins streams together
|
||||
process.openStdin(), //open stdin
|
||||
split(), //split stream to break on newlines
|
||||
es.map(function (data, callback) {//turn this async function into a stream
|
||||
var j
|
||||
try {
|
||||
j = JSON.parse(data) //try to parse input into json
|
||||
} catch (err) {
|
||||
return callback(null, data) //if it fails just pass it anyway
|
||||
}
|
||||
callback(null, inspect(j)) //render it nicely
|
||||
}),
|
||||
process.stdout // pipe it to stdout !
|
||||
)
|
||||
}
|
||||
|
||||
// run this
|
||||
//
|
||||
// curl -sS registry.npmjs.org/event-stream | node pretty.js
|
||||
//
|
59
node_modules/jsftp/node_modules/event-stream/node_modules/split/index.js
generated
vendored
Normal file
59
node_modules/jsftp/node_modules/event-stream/node_modules/split/index.js
generated
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
//filter will reemit the data if cb(err,pass) pass is truthy
|
||||
|
||||
// reduce is more tricky
|
||||
// maybe we want to group the reductions or emit progress updates occasionally
|
||||
// the most basic reduce just emits one 'data' event after it has recieved 'end'
|
||||
|
||||
|
||||
var through = require('through')
|
||||
var Decoder = require('string_decoder').StringDecoder
|
||||
|
||||
module.exports = split
|
||||
|
||||
//TODO pass in a function to map across the lines.
|
||||
|
||||
function split (matcher, mapper) {
|
||||
var decoder = new Decoder()
|
||||
var soFar = ''
|
||||
if('function' === typeof matcher)
|
||||
mapper = matcher, matcher = null
|
||||
if (!matcher)
|
||||
matcher = /\r?\n/
|
||||
|
||||
function emit(stream, piece) {
|
||||
if(mapper) {
|
||||
try {
|
||||
piece = mapper(piece)
|
||||
}
|
||||
catch (err) {
|
||||
return stream.emit('error', err)
|
||||
}
|
||||
if('undefined' !== typeof piece)
|
||||
stream.queue(piece)
|
||||
}
|
||||
else
|
||||
stream.queue(piece)
|
||||
}
|
||||
|
||||
function next (stream, buffer) {
|
||||
var pieces = (soFar + buffer).split(matcher)
|
||||
soFar = pieces.pop()
|
||||
|
||||
for (var i = 0; i < pieces.length; i++) {
|
||||
var piece = pieces[i]
|
||||
emit(stream, piece)
|
||||
}
|
||||
}
|
||||
|
||||
return through(function (b) {
|
||||
next(this, decoder.write(b))
|
||||
},
|
||||
function () {
|
||||
if(decoder.end)
|
||||
next(this, decoder.end())
|
||||
if(soFar != null)
|
||||
emit(this, soFar)
|
||||
this.queue(null)
|
||||
})
|
||||
}
|
||||
|
38
node_modules/jsftp/node_modules/event-stream/node_modules/split/package.json
generated
vendored
Normal file
38
node_modules/jsftp/node_modules/event-stream/node_modules/split/package.json
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"name": "split",
|
||||
"version": "0.2.10",
|
||||
"description": "split a Text Stream into a Line Stream",
|
||||
"homepage": "http://github.com/dominictarr/split",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/dominictarr/split.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"through": "2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"asynct": "*",
|
||||
"it-is": "1",
|
||||
"ubelt": "~2.9",
|
||||
"stream-spec": "~0.2",
|
||||
"event-stream": "~3.0.2"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "asynct test/"
|
||||
},
|
||||
"author": {
|
||||
"name": "Dominic Tarr",
|
||||
"email": "dominic.tarr@gmail.com",
|
||||
"url": "http://bit.ly/dominictarr"
|
||||
},
|
||||
"optionalDependencies": {},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"readme": "# Split (matcher)\n\n[![build status](https://secure.travis-ci.org/dominictarr/split.png)](http://travis-ci.org/dominictarr/split)\n\nBreak up a stream and reassemble it so that each line is a chunk. matcher may be a `String`, or a `RegExp` \n\nExample, read every line in a file ...\n\n``` js\n fs.createReadStream(file)\n .pipe(split())\n .on('data', function (line) {\n //each chunk now is a seperate line!\n })\n\n```\n\n`split` takes the same arguments as `string.split` except it defaults to '/\\r?\\n/' instead of ',', and the optional `limit` paremeter is ignored.\n[String#split](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/split)\n\n# NDJ - Newline Delimited Json\n\n`split` accepts a function which transforms each line.\n\n``` js\nfs.createReadStream(file)\n .pipe(split(JSON.parse))\n .on('data', function (obj) {\n //each chunk now is a a js object\n })\n .on('error', function (err) {\n //syntax errors will land here\n //note, this ends the stream.\n })\n```\n\n# License\n\nMIT\n",
|
||||
"_id": "split@0.2.10",
|
||||
"dist": {
|
||||
"shasum": "f3df4e839e7f9dc513d5463b1c8ad95d4bf75e85"
|
||||
},
|
||||
"_from": "split@0.2"
|
||||
}
|
39
node_modules/jsftp/node_modules/event-stream/node_modules/split/readme.markdown
generated
vendored
Normal file
39
node_modules/jsftp/node_modules/event-stream/node_modules/split/readme.markdown
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
# Split (matcher)
|
||||
|
||||
[![build status](https://secure.travis-ci.org/dominictarr/split.png)](http://travis-ci.org/dominictarr/split)
|
||||
|
||||
Break up a stream and reassemble it so that each line is a chunk. matcher may be a `String`, or a `RegExp`
|
||||
|
||||
Example, read every line in a file ...
|
||||
|
||||
``` js
|
||||
fs.createReadStream(file)
|
||||
.pipe(split())
|
||||
.on('data', function (line) {
|
||||
//each chunk now is a seperate line!
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
`split` takes the same arguments as `string.split` except it defaults to '/\r?\n/' instead of ',', and the optional `limit` paremeter is ignored.
|
||||
[String#split](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/split)
|
||||
|
||||
# NDJ - Newline Delimited Json
|
||||
|
||||
`split` accepts a function which transforms each line.
|
||||
|
||||
``` js
|
||||
fs.createReadStream(file)
|
||||
.pipe(split(JSON.parse))
|
||||
.on('data', function (obj) {
|
||||
//each chunk now is a a js object
|
||||
})
|
||||
.on('error', function (err) {
|
||||
//syntax errors will land here
|
||||
//note, this ends the stream.
|
||||
})
|
||||
```
|
||||
|
||||
# License
|
||||
|
||||
MIT
|
34
node_modules/jsftp/node_modules/event-stream/node_modules/split/test/partitioned_unicode.js
generated
vendored
Normal file
34
node_modules/jsftp/node_modules/event-stream/node_modules/split/test/partitioned_unicode.js
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
var it = require('it-is').style('colour')
|
||||
, split = require('..')
|
||||
|
||||
exports ['split data with partitioned unicode character'] = function (test) {
|
||||
var s = split(/,/g)
|
||||
, caughtError = false
|
||||
, rows = []
|
||||
|
||||
s.on('error', function (err) {
|
||||
caughtError = true
|
||||
})
|
||||
|
||||
s.on('data', function (row) { rows.push(row) })
|
||||
|
||||
var x = 'テスト試験今日とても,よい天気で'
|
||||
unicodeData = new Buffer(x);
|
||||
|
||||
// partition of 日
|
||||
piece1 = unicodeData.slice(0, 20);
|
||||
piece2 = unicodeData.slice(20, unicodeData.length);
|
||||
|
||||
s.write(piece1);
|
||||
s.write(piece2);
|
||||
|
||||
s.end()
|
||||
|
||||
it(caughtError).equal(false)
|
||||
|
||||
it(rows).deepEqual(['テスト試験今日とても', 'よい天気で']);
|
||||
|
||||
it(rows).deepEqual(x.split(','))
|
||||
|
||||
test.done()
|
||||
}
|
85
node_modules/jsftp/node_modules/event-stream/node_modules/split/test/split.asynct.js
generated
vendored
Normal file
85
node_modules/jsftp/node_modules/event-stream/node_modules/split/test/split.asynct.js
generated
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
var es = require('event-stream')
|
||||
, it = require('it-is').style('colour')
|
||||
, d = require('ubelt')
|
||||
, split = require('..')
|
||||
, join = require('path').join
|
||||
, fs = require('fs')
|
||||
, Stream = require('stream').Stream
|
||||
, spec = require('stream-spec')
|
||||
|
||||
exports ['split() works like String#split'] = function (test) {
|
||||
var readme = join(__filename)
|
||||
, expected = fs.readFileSync(readme, 'utf-8').split('\n')
|
||||
, cs = split()
|
||||
, actual = []
|
||||
, ended = false
|
||||
, x = spec(cs).through()
|
||||
|
||||
var a = new Stream ()
|
||||
|
||||
a.write = function (l) {
|
||||
actual.push(l.trim())
|
||||
}
|
||||
a.end = function () {
|
||||
|
||||
ended = true
|
||||
expected.forEach(function (v,k) {
|
||||
//String.split will append an empty string ''
|
||||
//if the string ends in a split pattern.
|
||||
//es.split doesn't which was breaking this test.
|
||||
//clearly, appending the empty string is correct.
|
||||
//tests are passing though. which is the current job.
|
||||
if(v)
|
||||
it(actual[k]).like(v)
|
||||
})
|
||||
//give the stream time to close
|
||||
process.nextTick(function () {
|
||||
test.done()
|
||||
x.validate()
|
||||
})
|
||||
}
|
||||
a.writable = true
|
||||
|
||||
fs.createReadStream(readme, {flags: 'r'}).pipe(cs)
|
||||
cs.pipe(a)
|
||||
|
||||
}
|
||||
|
||||
exports ['split() takes mapper function'] = function (test) {
|
||||
var readme = join(__filename)
|
||||
, expected = fs.readFileSync(readme, 'utf-8').split('\n')
|
||||
, cs = split(function (line) { return line.toUpperCase() })
|
||||
, actual = []
|
||||
, ended = false
|
||||
, x = spec(cs).through()
|
||||
|
||||
var a = new Stream ()
|
||||
|
||||
a.write = function (l) {
|
||||
actual.push(l.trim())
|
||||
}
|
||||
a.end = function () {
|
||||
|
||||
ended = true
|
||||
expected.forEach(function (v,k) {
|
||||
//String.split will append an empty string ''
|
||||
//if the string ends in a split pattern.
|
||||
//es.split doesn't which was breaking this test.
|
||||
//clearly, appending the empty string is correct.
|
||||
//tests are passing though. which is the current job.
|
||||
if(v)
|
||||
it(actual[k]).equal(v.trim().toUpperCase())
|
||||
})
|
||||
//give the stream time to close
|
||||
process.nextTick(function () {
|
||||
test.done()
|
||||
x.validate()
|
||||
})
|
||||
}
|
||||
a.writable = true
|
||||
|
||||
fs.createReadStream(readme, {flags: 'r'}).pipe(cs)
|
||||
cs.pipe(a)
|
||||
|
||||
}
|
||||
|
51
node_modules/jsftp/node_modules/event-stream/node_modules/split/test/try_catch.asynct.js
generated
vendored
Normal file
51
node_modules/jsftp/node_modules/event-stream/node_modules/split/test/try_catch.asynct.js
generated
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
var it = require('it-is').style('colour')
|
||||
, split = require('..')
|
||||
|
||||
exports ['emit mapper exceptions as error events'] = function (test) {
|
||||
var s = split(JSON.parse)
|
||||
, caughtError = false
|
||||
, rows = []
|
||||
|
||||
s.on('error', function (err) {
|
||||
caughtError = true
|
||||
})
|
||||
|
||||
s.on('data', function (row) { rows.push(row) })
|
||||
|
||||
s.write('{"a":1}\n{"')
|
||||
it(caughtError).equal(false)
|
||||
it(rows).deepEqual([ { a: 1 } ])
|
||||
|
||||
s.write('b":2}\n{"c":}\n')
|
||||
it(caughtError).equal(true)
|
||||
it(rows).deepEqual([ { a: 1 }, { b: 2 } ])
|
||||
|
||||
s.end()
|
||||
test.done()
|
||||
}
|
||||
|
||||
exports ['mapper error events on trailing chunks'] = function (test) {
|
||||
var s = split(JSON.parse)
|
||||
, caughtError = false
|
||||
, rows = []
|
||||
|
||||
s.on('error', function (err) {
|
||||
caughtError = true
|
||||
})
|
||||
|
||||
s.on('data', function (row) { rows.push(row) })
|
||||
|
||||
s.write('{"a":1}\n{"')
|
||||
it(caughtError).equal(false)
|
||||
it(rows).deepEqual([ { a: 1 } ])
|
||||
|
||||
s.write('b":2}\n{"c":}')
|
||||
it(caughtError).equal(false)
|
||||
it(rows).deepEqual([ { a: 1 }, { b: 2 } ])
|
||||
|
||||
s.end()
|
||||
it(caughtError).equal(true)
|
||||
it(rows).deepEqual([ { a: 1 }, { b: 2 } ])
|
||||
|
||||
test.done()
|
||||
}
|
3
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/.npmignore
generated
vendored
Normal file
3
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/.npmignore
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
node_modules
|
||||
node_modules/*
|
||||
npm_debug.log
|
4
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/.travis.yml
generated
vendored
Normal file
4
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 0.6
|
||||
- 0.8
|
22
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/LICENSE
generated
vendored
Normal file
22
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 2012 'Dominic Tarr'
|
||||
|
||||
Permission is hereby granted, free of charge,
|
||||
to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify,
|
||||
merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
29
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/README.md
generated
vendored
Normal file
29
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/README.md
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
# stream-combiner
|
||||
|
||||
<img src=https://secure.travis-ci.org/dominictarr/stream-combiner.png?branch=master>
|
||||
|
||||
## pipeline (stream1,...,streamN)
|
||||
|
||||
Turn a pipeline into a single stream. `pipeline` returns a stream that writes to the first stream
|
||||
and reads from the last stream.
|
||||
|
||||
Listening for 'error' will recieve errors from all streams inside the pipe.
|
||||
|
||||
> `connect` is an alias for `pipeline`.
|
||||
|
||||
``` js
|
||||
|
||||
es.pipeline( //connect streams together with `pipe`
|
||||
process.openStdin(), //open stdin
|
||||
es.split(), //split stream to break on newlines
|
||||
es.map(function (data, callback) {//turn this async function into a stream
|
||||
callback(null
|
||||
, inspect(JSON.parse(data))) //render it nicely
|
||||
}),
|
||||
process.stdout // pipe it to stdout !
|
||||
)
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
39
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/index.js
generated
vendored
Normal file
39
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/index.js
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
var duplexer = require('duplexer')
|
||||
|
||||
module.exports = function () {
|
||||
|
||||
var streams = [].slice.call(arguments)
|
||||
, first = streams[0]
|
||||
, last = streams[streams.length - 1]
|
||||
, thepipe = duplexer(first, last)
|
||||
|
||||
if(streams.length == 1)
|
||||
return streams[0]
|
||||
else if (!streams.length)
|
||||
throw new Error('connect called with empty args')
|
||||
|
||||
//pipe all the streams together
|
||||
|
||||
function recurse (streams) {
|
||||
if(streams.length < 2)
|
||||
return
|
||||
streams[0].pipe(streams[1])
|
||||
recurse(streams.slice(1))
|
||||
}
|
||||
|
||||
recurse(streams)
|
||||
|
||||
function onerror () {
|
||||
var args = [].slice.call(arguments)
|
||||
args.unshift('error')
|
||||
thepipe.emit.apply(thepipe, args)
|
||||
}
|
||||
|
||||
//es.duplex already reemits the error from the first and last stream.
|
||||
//add a listener for the inner streams in the pipeline.
|
||||
for(var i = 1; i < streams.length - 1; i ++)
|
||||
streams[i].on('error', onerror)
|
||||
|
||||
return thepipe
|
||||
}
|
||||
|
3
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/node_modules/duplexer/.npmignore
generated
vendored
Normal file
3
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/node_modules/duplexer/.npmignore
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
node_modules
|
||||
*.log
|
||||
*.err
|
3
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/node_modules/duplexer/.travis.yml
generated
vendored
Normal file
3
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/node_modules/duplexer/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 0.8
|
19
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/node_modules/duplexer/LICENCE
generated
vendored
Normal file
19
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/node_modules/duplexer/LICENCE
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2012 Raynos.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
4
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/node_modules/duplexer/Makefile
generated
vendored
Normal file
4
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/node_modules/duplexer/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
test:
|
||||
node test.js
|
||||
|
||||
.PHONY: test
|
36
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/node_modules/duplexer/README.md
generated
vendored
Normal file
36
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/node_modules/duplexer/README.md
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
# duplexer [![build status][1]][2]
|
||||
|
||||
Creates a duplex stream
|
||||
|
||||
Taken from [event-stream][3]
|
||||
|
||||
## duplex (writeStream, readStream)
|
||||
|
||||
Takes a writable stream and a readable stream and makes them appear as a readable writable stream.
|
||||
|
||||
It is assumed that the two streams are connected to each other in some way.
|
||||
|
||||
## Example
|
||||
|
||||
var grep = cp.exec('grep Stream')
|
||||
|
||||
duplex(grep.stdin, grep.stdout)
|
||||
|
||||
## Installation
|
||||
|
||||
`npm install duplexer`
|
||||
|
||||
## Tests
|
||||
|
||||
`make test`
|
||||
|
||||
## Contributors
|
||||
|
||||
- Dominictarr
|
||||
- Raynos
|
||||
|
||||
## MIT Licenced
|
||||
|
||||
[1]: https://secure.travis-ci.org/Raynos/duplexer.png
|
||||
[2]: http://travis-ci.org/Raynos/duplexer
|
||||
[3]: https://github.com/dominictarr/event-stream#duplex-writestream-readstream
|
87
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/node_modules/duplexer/index.js
generated
vendored
Normal file
87
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/node_modules/duplexer/index.js
generated
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
var Stream = require("stream")
|
||||
, writeMethods = ["write", "end", "destroy"]
|
||||
, readMethods = ["resume", "pause"]
|
||||
, readEvents = ["data", "close"]
|
||||
, slice = Array.prototype.slice
|
||||
|
||||
module.exports = duplex
|
||||
|
||||
function duplex(writer, reader) {
|
||||
var stream = new Stream()
|
||||
, ended = false
|
||||
|
||||
Object.defineProperties(stream, {
|
||||
writable: {
|
||||
get: getWritable
|
||||
}
|
||||
, readable: {
|
||||
get: getReadable
|
||||
}
|
||||
})
|
||||
|
||||
writeMethods.forEach(proxyWriter)
|
||||
|
||||
readMethods.forEach(proxyReader)
|
||||
|
||||
readEvents.forEach(proxyStream)
|
||||
|
||||
reader.on("end", handleEnd)
|
||||
|
||||
writer.on("error", reemit)
|
||||
reader.on("error", reemit)
|
||||
|
||||
return stream
|
||||
|
||||
function getWritable() {
|
||||
return writer.writable
|
||||
}
|
||||
|
||||
function getReadable() {
|
||||
return reader.readable
|
||||
}
|
||||
|
||||
function proxyWriter(methodName) {
|
||||
stream[methodName] = method
|
||||
|
||||
function method() {
|
||||
return writer[methodName].apply(writer, arguments)
|
||||
}
|
||||
}
|
||||
|
||||
function proxyReader(methodName) {
|
||||
stream[methodName] = method
|
||||
|
||||
function method() {
|
||||
stream.emit(methodName)
|
||||
var func = reader[methodName]
|
||||
if (func) {
|
||||
return func.apply(reader, arguments)
|
||||
}
|
||||
reader.emit(methodName)
|
||||
}
|
||||
}
|
||||
|
||||
function proxyStream(methodName) {
|
||||
reader.on(methodName, reemit)
|
||||
|
||||
function reemit() {
|
||||
var args = slice.call(arguments)
|
||||
args.unshift(methodName)
|
||||
stream.emit.apply(stream, args)
|
||||
}
|
||||
}
|
||||
|
||||
function handleEnd() {
|
||||
if (ended) {
|
||||
return
|
||||
}
|
||||
ended = true
|
||||
var args = slice.call(arguments)
|
||||
args.unshift("end")
|
||||
stream.emit.apply(stream, args)
|
||||
}
|
||||
|
||||
function reemit(err) {
|
||||
stream.emit("error", err)
|
||||
}
|
||||
}
|
44
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/node_modules/duplexer/package.json
generated
vendored
Normal file
44
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/node_modules/duplexer/package.json
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"name": "duplexer",
|
||||
"version": "0.0.2",
|
||||
"description": "Creates a duplex stream",
|
||||
"keywords": [],
|
||||
"author": {
|
||||
"name": "Raynos",
|
||||
"email": "raynos2@gmail.com"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/Raynos/duplexer.git"
|
||||
},
|
||||
"main": "index",
|
||||
"homepage": "https://github.com/Raynos/duplexer",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Jake Verbaten"
|
||||
}
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/Raynos/duplexer/issues",
|
||||
"email": "raynos2@gmail.com"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"through": "~0.1.4"
|
||||
},
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT",
|
||||
"url": "http://github.com/Raynos/duplexer/raw/master/LICENSE"
|
||||
}
|
||||
],
|
||||
"scripts": {
|
||||
"test": "make test"
|
||||
},
|
||||
"readme": "# duplexer [![build status][1]][2]\n\nCreates a duplex stream\n\nTaken from [event-stream][3]\n\n## duplex (writeStream, readStream)\n\nTakes a writable stream and a readable stream and makes them appear as a readable writable stream.\n\nIt is assumed that the two streams are connected to each other in some way.\n\n## Example\n\n var grep = cp.exec('grep Stream')\n\n duplex(grep.stdin, grep.stdout)\n\n## Installation\n\n`npm install duplexer`\n\n## Tests\n\n`make test`\n\n## Contributors\n\n - Dominictarr\n - Raynos\n\n## MIT Licenced\n\n [1]: https://secure.travis-ci.org/Raynos/duplexer.png\n [2]: http://travis-ci.org/Raynos/duplexer\n [3]: https://github.com/dominictarr/event-stream#duplex-writestream-readstream",
|
||||
"_id": "duplexer@0.0.2",
|
||||
"dist": {
|
||||
"shasum": "21b2a2e78861eea18bb080cb9491cbcd193ead08"
|
||||
},
|
||||
"_from": "duplexer@0.0.2"
|
||||
}
|
27
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/node_modules/duplexer/test.js
generated
vendored
Normal file
27
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/node_modules/duplexer/test.js
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
var duplex = require("./index")
|
||||
, assert = require("assert")
|
||||
, through = require("through")
|
||||
|
||||
var readable = through()
|
||||
, writable = through(write)
|
||||
, written = 0
|
||||
, data = 0
|
||||
|
||||
var stream = duplex(writable, readable)
|
||||
|
||||
function write() {
|
||||
written++
|
||||
}
|
||||
|
||||
stream.on("data", ondata)
|
||||
|
||||
function ondata() {
|
||||
data++
|
||||
}
|
||||
|
||||
stream.write()
|
||||
readable.emit("data")
|
||||
|
||||
assert.equal(written, 1)
|
||||
assert.equal(data, 1)
|
||||
console.log("DONE")
|
32
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/package.json
generated
vendored
Normal file
32
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/package.json
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"name": "stream-combiner",
|
||||
"version": "0.0.0",
|
||||
"homepage": "https://github.com/dominictarr/stream-combiner",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/dominictarr/stream-combiner.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"duplexer": "0.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tape": "0.0.4",
|
||||
"event-stream": "~3.0.7"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "set -e; for t in test/*.js; do node $t; done"
|
||||
},
|
||||
"author": {
|
||||
"name": "'Dominic Tarr'",
|
||||
"email": "dominic.tarr@gmail.com",
|
||||
"url": "http://dominictarr.com"
|
||||
},
|
||||
"license": "MIT",
|
||||
"readme": "# stream-combiner\n\n<img src=https://secure.travis-ci.org/dominictarr/stream-combiner.png?branch=master>\n\n## pipeline (stream1,...,streamN)\n\nTurn a pipeline into a single stream. `pipeline` returns a stream that writes to the first stream\nand reads from the last stream. \n\nListening for 'error' will recieve errors from all streams inside the pipe.\n\n> `connect` is an alias for `pipeline`.\n\n``` js\n\n es.pipeline( //connect streams together with `pipe`\n process.openStdin(), //open stdin\n es.split(), //split stream to break on newlines\n es.map(function (data, callback) {//turn this async function into a stream\n callback(null\n , inspect(JSON.parse(data))) //render it nicely\n }),\n process.stdout // pipe it to stdout !\n )\n```\n\n## License\n\nMIT\n",
|
||||
"_id": "stream-combiner@0.0.0",
|
||||
"description": "<img src=https://secure.travis-ci.org/dominictarr/stream-combiner.png?branch=master>",
|
||||
"dist": {
|
||||
"shasum": "e0b7200a986c630eef402100cef434714b4db89c"
|
||||
},
|
||||
"_from": "stream-combiner@0.0.0"
|
||||
}
|
52
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/test/index.js
generated
vendored
Normal file
52
node_modules/jsftp/node_modules/event-stream/node_modules/stream-combiner/test/index.js
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
var es = require('event-stream')
|
||||
var combine = require('..')
|
||||
var test = require('tape')
|
||||
|
||||
test('do not duplicate errors', function (test) {
|
||||
|
||||
var errors = 0;
|
||||
var pipe = combine(
|
||||
es.through(function(data) {
|
||||
return this.emit('data', data);
|
||||
}),
|
||||
es.through(function(data) {
|
||||
return this.emit('error', new Error(data));
|
||||
})
|
||||
)
|
||||
|
||||
pipe.on('error', function(err) {
|
||||
errors++
|
||||
test.ok(errors, 'expected error count')
|
||||
process.nextTick(function () {
|
||||
return test.end();
|
||||
})
|
||||
})
|
||||
|
||||
return pipe.write('meh');
|
||||
})
|
||||
|
||||
test('3 pipe do not duplicate errors', function (test) {
|
||||
|
||||
var errors = 0;
|
||||
var pipe = combine(
|
||||
es.through(function(data) {
|
||||
return this.emit('data', data);
|
||||
}),
|
||||
es.through(function(data) {
|
||||
return this.emit('error', new Error(data));
|
||||
}),
|
||||
es.through()
|
||||
)
|
||||
|
||||
pipe.on('error', function(err) {
|
||||
errors++
|
||||
test.ok(errors, 'expected error count')
|
||||
process.nextTick(function () {
|
||||
return test.end();
|
||||
})
|
||||
})
|
||||
|
||||
return pipe.write('meh');
|
||||
|
||||
})
|
||||
|
5
node_modules/jsftp/node_modules/event-stream/node_modules/through/.travis.yml
generated
vendored
Normal file
5
node_modules/jsftp/node_modules/event-stream/node_modules/through/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 0.6
|
||||
- 0.8
|
||||
- "0.10"
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue