diff --git a/README.md b/README.md index e4007bb..37802e3 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ contents and returns the desired contents. pipelines in both buffer mode and streaming mode. * **Economical**. Reduce the need for gulp-specific plugins by pairing gulp-transform with ordinary node packages and functions. - +* **Async**-ready. Transform is supported by returning `Promise` from transform function. ## Install Install via [npm][NPM link]: @@ -89,9 +89,9 @@ gulp.task('cheerio', function() { ##### transformFn `function` -The callback responsible for the transformation. The return value must be a -string or a Buffer, which will replace the file's contents. The callback -is invoked once per file with the following arguments: +The callback responsible for the transformation. The return value must be value or +Promise resolvable to string or a Buffer, which will replace the file's contents. +The callbackis invoked once per file with the following arguments: * **contents** `Buffer` | `string`
The initial contents of the file. Contents are passed as a Buffer unless the diff --git a/src/file-stream.js b/src/file-stream.js index d2250d6..a6ae06c 100644 --- a/src/file-stream.js +++ b/src/file-stream.js @@ -18,10 +18,16 @@ export class FileStream extends Transform { } _flush(done) { + let self = this; let contents = Buffer.concat(this.data); - this.push(transform(this.fn, contents, this.file, this.opts)); - - done(); + transform(this.fn, contents, this.file, this.opts) + .then(function(contents) { + self.push(contents); + done(); + }) + .catch(function(error) { + done(error) + }) } } diff --git a/src/plugin-stream.js b/src/plugin-stream.js index 2fc649e..28b5f49 100644 --- a/src/plugin-stream.js +++ b/src/plugin-stream.js @@ -15,14 +15,17 @@ export class PluginStream extends Transform { let {fn, opts} = this; if (file.isBuffer()) { - file.contents = transform(fn, file.contents, file, opts); - } - - if (file.isStream()) { + transform(fn, file.contents, file, opts) + .then(function(contents) { + file.contents = contents; + next(null, file) + }) + .catch(function(error) { + next(error); + }) + } else if (file.isStream()) { file.contents = file.contents.pipe(new FileStream(fn, file, opts)); + next(null, file); } - - next(null, file); } - } diff --git a/src/transform.js b/src/transform.js index fe09458..323a3dc 100644 --- a/src/transform.js +++ b/src/transform.js @@ -3,9 +3,10 @@ import {err} from './err'; export function transform(fn, contents, file, opts) { let encoded = opts.encoding ? contents.toString(opts.encoding) : contents; - let transformed = fn.call(opts.thisArg, encoded, file); - - return isBuffer(transformed) ? transformed : - isString(transformed) ? new Buffer(transformed) : - err('transformFn must return a string or a Buffer'); + return Promise.resolve(fn.call(opts.thisArg, encoded, file)) + .then(function(transformed) { + return isBuffer(transformed) ? transformed : + isString(transformed) ? new Buffer(transformed) : + err('transformFn must return a string or a Buffer'); + }) } diff --git a/test/index.coffee b/test/index.coffee index 17cb3cb..49c5364 100644 --- a/test/index.coffee +++ b/test/index.coffee @@ -32,8 +32,13 @@ describe 'plugin: gulp-transform', -> context 'returns neither a string nor a Buffer', -> - it 'throws PluginError', -> - err -> transform((content) -> 42).write buffered() + it 'throws PluginError', (done) -> + t = transform((content) -> 42) + t.on 'error', (err) -> + done() + t.on 'data', () -> + done new Error('expected PluginError') + t.write buffered() context 'returns a Buffer or string', -> [fn, file] = [null, null]