gulp-webdav-sync
Advanced tools
Comparing version 0.4.0 to 0.5.0
197
index.js
@@ -6,4 +6,40 @@ var chalk = require( 'chalk' ) | ||
var Stream = require( 'stream' ) | ||
var underscore = require( 'underscore' ) | ||
if ( !Object.assign ) { | ||
Object.defineProperty( Object, 'assign', { | ||
configurable: true | ||
, enumerable: false | ||
, value: function ( target ) { | ||
if ( target === undefined || target === null ) { | ||
throw new TypeError( 'Cannot convert first argument to object' ) | ||
} | ||
var to = Object( target ) | ||
var nextSource | ||
for ( var i = 1 ; i < arguments.length ; i++ ) { | ||
nextSource = arguments[i] | ||
if ( nextSource === undefined || nextSource === null ) { | ||
continue | ||
} | ||
nextSource = Object( nextSource ) | ||
var keysArray = Object.keys( Object( nextSource ) ) | ||
keysArray.forEach( assignKey ) | ||
} | ||
function assignKey( e, i, a ) { | ||
var nextKey = a[i] | ||
var desc = Object.getOwnPropertyDescriptor( nextSource, nextKey ) | ||
if ( desc !== undefined && desc.enumerable ) { | ||
to[nextKey] = nextSource[nextKey] | ||
} | ||
} | ||
return to | ||
} | ||
, writable: true | ||
} ) | ||
} | ||
var underscore = { | ||
extend: function () { | ||
return Object.assign.apply( null, arguments ) | ||
} | ||
} | ||
var url = require( 'url' ) | ||
var xml2js = require( 'xml2js' ) | ||
@@ -18,2 +54,3 @@ const PLUGIN_NAME = 'gulp-webdav-sync' | ||
'agent': false | ||
, 'clean': false | ||
, 'log': 'error' | ||
@@ -56,2 +93,3 @@ , 'logAuth': false | ||
} | ||
_info_target( href ) | ||
stream = new Stream.Transform( { objectMode: true } ) | ||
@@ -70,2 +108,3 @@ stream._transform = function ( vinyl, encoding, callback ) { | ||
var target_uri | ||
var target_stem | ||
try { | ||
@@ -78,2 +117,7 @@ log.log( _gulp_prefix( FN_NAME + '$href' ), href ) | ||
) | ||
target_stem = _splice_target_stem( | ||
vinyl.path | ||
, path.resolve( _options.parent ) | ||
, href | ||
) | ||
} catch ( error ) { | ||
@@ -85,3 +129,3 @@ _on_error( error ) | ||
log.log( _gulp_prefix( FN_NAME + '$target_uri' ), target_uri ) | ||
_info_target( vinyl.path, target_uri ) | ||
_info_path( target_stem ) | ||
if ( vinyl.event === 'unlink' ) { | ||
@@ -91,2 +135,6 @@ _delete( target_uri, resume ) | ||
} | ||
if ( _options.clean ) { | ||
_delete( target_uri, resume ) | ||
return | ||
} | ||
if ( vinyl.isBuffer() ) { | ||
@@ -130,3 +178,8 @@ _put( target_uri, vinyl, resume ) | ||
) | ||
_info_target( glob_watcher.path, target_uri ) | ||
var target_stem = _splice_target_stem( | ||
glob_watcher.path | ||
, path.resolve( _options.parent ) | ||
, href | ||
) | ||
_info_path( target_stem ) | ||
_delete( target_uri, function ( res ) { | ||
@@ -144,29 +197,44 @@ _info_status( res.statusCode ) | ||
} | ||
stream.clean = function ( cb ) { | ||
const FN_NAME = '#main#clean' | ||
var target_uri | ||
if ( _string ) { | ||
target_uri = _string | ||
} else { | ||
target_uri = url.parse( _options ) | ||
} | ||
log.log( _gulp_prefix( FN_NAME + '$target_uri' ), target_uri ) | ||
_options = underscore.extend( _options, { 'headers': { 'Depth': 1 } } ) | ||
_propfind( target_uri, function ( dom ) { | ||
var urls = _xml_to_url_a( dom ) | ||
urls = urls.map( | ||
function ( e ) { | ||
return url.resolve( target_uri, e ) | ||
} | ||
).filter( | ||
function ( e ) { | ||
return e !== target_uri | ||
} | ||
) | ||
log.log( 'postmap', urls ) | ||
function d( urls ) { | ||
if ( urls.length > 0 ) { | ||
_delete( urls.pop() | ||
, function ( res ) { | ||
_info_status( res.statusCode ) | ||
d( urls ) | ||
} | ||
) | ||
} else { | ||
if ( cb ) { | ||
cb() | ||
} | ||
} | ||
} | ||
d( urls ) | ||
} ) | ||
} | ||
return stream | ||
} | ||
function _align_right() { | ||
var max = underscore.chain( arguments ) | ||
.map( function ( x ) { | ||
return x.length | ||
} ) | ||
.max() | ||
.value() | ||
return underscore.map( | ||
arguments | ||
, function ( x ) { | ||
var diff = max - x.length | ||
var pref = [] | ||
underscore.times( | ||
diff | ||
, function () { | ||
pref.push( ' ' ) | ||
} | ||
) | ||
pref.push( x ) | ||
return pref.join( '' ) | ||
} | ||
) | ||
} | ||
function _colorcode_statusCode_fn( statusCode ) { | ||
@@ -190,2 +258,3 @@ switch ( statusCode ) { | ||
case 424: | ||
case 500: | ||
case 502: | ||
@@ -217,2 +286,3 @@ case 507: | ||
case 424: | ||
case 500: | ||
case 502: | ||
@@ -243,8 +313,15 @@ case 507: | ||
function _gulp_prefix() { | ||
var time = '[' + chalk.grey( ( new Date() ).toLocaleTimeString() ) + ']' | ||
var name = '[' + chalk.grey( PLUGIN_NAME ) + ']' | ||
var item = chalk.grey( arguments[0] ) | ||
return [ time, name, item ].join( ' ' ) | ||
var item = '' | ||
for ( var i = 0 ; i < arguments.length ; i++ ) { | ||
item += chalk.grey( arguments[i] ) | ||
} | ||
return [ name, item ].join( ' ' ) | ||
} | ||
function _info_path( string ) { | ||
var out = chalk.underline( string ) | ||
log.info( _gulp_prefix(), out ) | ||
} | ||
function _info_status( statusCode ) { | ||
@@ -260,10 +337,8 @@ var code = | ||
function _info_target( vinyl_path, uri ) { | ||
function _info_target( uri ) { | ||
if ( _options.logAuth !== true ) { | ||
uri = _strip_url_auth( uri ) | ||
} | ||
var from = chalk.underline.cyan( vinyl_path ) | ||
var to = chalk.underline.cyan( uri ) | ||
log.info( ' ', _align_right( to, from )[1] ) | ||
log.info( ' ', _align_right( to, from )[0] ) | ||
log.info( _gulp_prefix(), to ) | ||
} | ||
@@ -301,2 +376,27 @@ | ||
function _propfind( uri, callback ) { | ||
var options, req | ||
options = underscore.extend( | ||
_options | ||
, url.parse( uri ) | ||
, { method: 'PROPFIND' } | ||
) | ||
req = http.request( options, function ( res ) { | ||
var body = '' | ||
res.on( 'data', function ( chunk ) { | ||
body += chunk | ||
} ) | ||
res.on( 'end', function () { | ||
var opt = { | ||
tagNameProcessors: [ xml2js.processors.stripPrefix ] | ||
} | ||
xml2js.parseString( body, opt, function ( err, result ) { | ||
if ( err ) { | ||
_on_error( err ) | ||
} | ||
callback( result ) | ||
} ) | ||
} ) | ||
} ) | ||
req.on( 'error', _on_error ) | ||
req.end() | ||
} | ||
@@ -336,2 +436,13 @@ | ||
} | ||
target_stem = _splice_target_stem( vinyl_path, parent_dir, href ) | ||
if ( !href ) { | ||
href = '' | ||
} | ||
return href + target_stem | ||
} | ||
function _splice_target_stem( vinyl_path, parent_dir, href ) { | ||
const FN_NAME = '#_splice_target_stem' | ||
var error | ||
var target_stem | ||
if ( vinyl_path.substr( 0, parent_dir.length ) === parent_dir ) { | ||
@@ -350,7 +461,3 @@ target_stem = vinyl_path.substr( parent_dir.length+1 ) | ||
} | ||
log.log( _gulp_prefix( FN_NAME + '$target_stem' ), target_stem ) | ||
if ( !href ) { | ||
href = '' | ||
} | ||
return href + target_stem | ||
return target_stem | ||
} | ||
@@ -363,1 +470,13 @@ | ||
} | ||
function _xml_to_url_a( dom ) { | ||
var a = [] | ||
try { | ||
dom.multistatus.response.forEach( function ( e ) { | ||
a.push( e.href[0] ) | ||
} ) | ||
} catch ( e ) { | ||
throw e | ||
} | ||
return a | ||
} |
{ | ||
"name": "gulp-webdav-sync", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"description": "Put files and folders on a WebDAV server. Deploy with gulp", | ||
@@ -35,9 +35,9 @@ "repository": { | ||
"run-sequence": "~1.1.1", | ||
"vinyl": "~0.5.0", | ||
"underscore": "~1.8.3" | ||
"vinyl": "~0.5.0" | ||
}, | ||
"dependencies": { | ||
"chalk": "~1.1.0", | ||
"gulp-util": "~3.0.6" | ||
"gulp-util": "~3.0.6", | ||
"xml2js": "~0.4.10" | ||
} | ||
} |
@@ -5,2 +5,3 @@ # gulp-webdav-sync | ||
## Usage | ||
### URL String | ||
Nominally, pass a URL string. | ||
@@ -16,3 +17,3 @@ ```js | ||
``` | ||
### URL Object | ||
Extend a [URL object](https://nodejs.org/api/url.html#url_url_format_urlobj). | ||
@@ -39,3 +40,3 @@ ```js | ||
``` | ||
### Subdirectories | ||
Suppose the following directory tree, | ||
@@ -48,3 +49,3 @@ * project/ | ||
and this target . | ||
and this target, | ||
* localhost:8000/ | ||
@@ -55,3 +56,3 @@ * css/ | ||
Use the `'parent'` option to constrain the localpath mapping. | ||
use the `'parent'` option to constrain the localpath mapping, | ||
```js | ||
@@ -70,3 +71,3 @@ var webdav = require( 'gulp-webdav-sync' ) | ||
``` | ||
Otherwise, the result is this. | ||
otherwise, the result is this. | ||
* localhost:8000/ | ||
@@ -78,2 +79,3 @@ * dist/ | ||
### With gulp.watch | ||
[browser-sync](http://www.browsersync.io/docs/gulp/), [npmconf](https://www.npmjs.com/package/npmconf), and [.npmrc](https://docs.npmjs.com/files/npmrc) for a save-sync-reload solution. | ||
@@ -87,2 +89,5 @@ ```shell | ||
var npmconf = require( 'npmconf' ) | ||
var paths = { | ||
'js': [ '*.js', '!gulpfile.js' ] | ||
} | ||
var href | ||
@@ -95,3 +100,3 @@ var options = { | ||
browserSync.init( { proxy: href } ) | ||
gulp.watch( [ '*.js', '!gulpfile.js' ], [ 'deploy' ] ) | ||
gulp.watch( paths.js, [ 'deploy' ] ) | ||
.on( 'change', webdav( href, options ).watch ) | ||
@@ -102,3 +107,3 @@ .on( 'change', browserSync.reload ) | ||
gulp.task( 'deploy', [ 'load-npmrc' ], function () { | ||
return gulp.src( [ '*.js', '!gulpfile.js' ] ) | ||
return gulp.src( paths.js ) | ||
.pipe( webdav( href, options ) ) | ||
@@ -117,10 +122,11 @@ } ) | ||
With [gulp-watch](https://www.npmjs.com/package/gulp-watch), `gulp deploy` re-emits created, modified, and deleted files for upload. | ||
### With gulp-watch | ||
[gulp-watch](https://www.npmjs.com/package/gulp-watch) re-emits created, modified, and deleted files for upload. | ||
```js | ||
var watch = require( 'gulp-watch' ) | ||
var webdav = require( 'gulp-webdav-sync' ) | ||
var href = 'http://localhost' | ||
var paths = { | ||
js: [ '*.js', '!gulpfile.js' ] | ||
'js': [ '*.js', '!gulpfile.js' ] | ||
} | ||
var href = 'http://localhost' | ||
@@ -139,4 +145,7 @@ gulp.task( 'deploy', function () { | ||
### webdav( [ href ] [, options ] ).clean( [ cb ] ) | ||
Deletes all resources under `href`. | ||
### webdav( [ href ] [, options ] ).watch( event [, cb ] ) | ||
Callback adapter for `change` events from `gulp.watch()`. Only handles `type: 'deleted'` events. `gulp.src()` does not push deleted files; use this or [gulp-watch](https://github.com/floatdrop/gulp-watch) instead. Calls back regardless of `type:`. | ||
Callback adapter for `'change'` events from `gulp.watch`. Only handles `type: 'deleted'` events. `gulp.src` does not push deleted files; use this or [gulp-watch](https://github.com/floatdrop/gulp-watch) instead. Calls back regardless of `event.type`. | ||
@@ -151,8 +160,10 @@ #### event | ||
``` | ||
**Type:** `Object` | ||
**Type:** `Object`</br> | ||
**Default:** `undefined` | ||
#### cb | ||
Optional asynchronous callback method. | ||
**Type:** `Function` | ||
Optional, asynchronous, callback function. | ||
**Type:** `Function`</br> | ||
**Default:** `undefined` | ||
@@ -162,11 +173,26 @@ | ||
**Type:** `string`</br> | ||
**Default:** `undefined`</br> | ||
**Type:** `String`</br> | ||
**Default:** `undefined` | ||
## options | ||
Superset of [http.request options parameter](https://nodejs.org/api/http.html#http_http_request_options_callback), and [url.object](https://nodejs.org/api/url.html#url_url_format_urlobj). If any URL properties are defined, `protocol`, `hostname`, and `pathname` default to `http://localhost/`. | ||
Superset of [http.request options parameter](https://nodejs.org/api/http.html#http_http_request_options_callback), and [url.object](https://nodejs.org/api/url.html#url_url_format_urlobj). If any URL properties are defined, then `protocol`, `hostname`, and `pathname` are assigned to `http://localhost/`. | ||
**Type:** `Object`.</br> | ||
**Default:** `{}` | ||
**Type:** `Object`</br> | ||
**Default:** | ||
```js | ||
{ | ||
'agent': false | ||
, 'clean': false | ||
, 'log': 'error' | ||
, 'logAuth': false | ||
, 'parent': process.cwd() | ||
} | ||
``` | ||
### options.clean | ||
Deletes corresponding resources on server instead of uploading. Note, glob star-star will delete directories before contents are pushed. | ||
**Type:** `Boolean`</br> | ||
**Default:** `false` | ||
### options.log | ||
@@ -173,0 +199,0 @@ Logging threshold. Orthogonal to the `console` methods. |
@@ -308,2 +308,50 @@ var assert = require( 'assert' ) | ||
it( 'Should clean files on option' | ||
, function ( done ) { | ||
var expected_file = path.join( node, 'file' ) | ||
var expected_dir = path.join( node, 'dir' ) | ||
var expected_sub = path.join( node, 'dir/file' ) | ||
var file = fs.openSync( expected_file, 'w' ) | ||
fs.writeSync( file, MOCK ) | ||
fs.closeSync( file ) | ||
fs.mkdirSync( expected_dir ) | ||
var sub = fs.openSync( expected_sub, 'w' ) | ||
fs.writeSync( sub, MOCK ) | ||
fs.closeSync( sub ) | ||
assert( fs.existsSync( expected_file ), 'file exists' ) | ||
assert( fs.existsSync( expected_dir ), 'dir exists' ) | ||
assert( fs.existsSync( expected_sub ), 'sub exists' ) | ||
var mock_file = new Vinyl( { path: path.resolve( 'file' ) } ) | ||
var mock_dir = new Vinyl( { path: path.resolve( 'dir' ) } ) | ||
var mock_sub = new Vinyl( { path: path.resolve( 'dir/file' ) } ) | ||
var options = { | ||
clean: true | ||
} | ||
var unit = mod( HREF, options ) | ||
unit.write( mock_file, null, function () { | ||
unit.write( mock_dir, null, function () { | ||
unit.write( mock_sub, null, validate ) | ||
} ) | ||
} ) | ||
function validate() { | ||
assert.equal( | ||
fs.existsSync( expected_file ) | ||
, false | ||
, 'file exists' | ||
) | ||
assert.equal( | ||
fs.existsSync( expected_dir ) | ||
, false | ||
, 'dir exists' | ||
) | ||
assert.equal( | ||
fs.existsSync( expected_sub ) | ||
, false | ||
, 'sub exists' | ||
) | ||
done() | ||
} | ||
} | ||
) | ||
} ) | ||
@@ -365,2 +413,46 @@ | ||
describe( '#main().clean', function () { | ||
it( 'Should delete all files under target' | ||
, function ( done ) { | ||
var expected_file = path.join( node, 'file' ) | ||
var expected_dir = path.join( node, 'dir' ) | ||
var expected_sub = path.join( node, 'dir/file' ) | ||
var file = fs.openSync( expected_file, 'w' ) | ||
fs.writeSync( file, MOCK ) | ||
fs.closeSync( file ) | ||
fs.mkdirSync( expected_dir ) | ||
var sub = fs.openSync( expected_sub, 'w' ) | ||
fs.writeSync( sub, MOCK ) | ||
fs.closeSync( sub ) | ||
assert( fs.existsSync( expected_file ), 'file exists' ) | ||
assert( fs.existsSync( expected_dir ), 'dir exists' ) | ||
assert( fs.existsSync( expected_sub ), 'sub exists' ) | ||
var options = { | ||
} | ||
var unit = mod( HREF, options ) | ||
unit.clean( validate ) | ||
function validate() { | ||
assert.equal( | ||
fs.existsSync( expected_file ) | ||
, false | ||
, 'file exists' | ||
) | ||
assert.equal( | ||
fs.existsSync( expected_dir ) | ||
, false | ||
, 'dir exists' | ||
) | ||
assert.equal( | ||
fs.existsSync( expected_sub ) | ||
, false | ||
, 'sub exists' | ||
) | ||
done() | ||
} | ||
} | ||
) | ||
} ) | ||
} ) |
40224
12
12
915
218
3
+ Addedxml2js@~0.4.10
+ Addedsax@1.4.1(transitive)
+ Addedxml2js@0.4.23(transitive)
+ Addedxmlbuilder@11.0.1(transitive)