From f4244f77a9da5fceca5e8759c74dffb935804aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B9=BD=E9=96=92?= <34772477+superfreeeee@users.noreply.github.com> Date: Sun, 17 Dec 2023 21:40:39 +0800 Subject: [PATCH] Support editor to return PromiseLike object (#48) --- README.md | 2 +- index.js | 44 ++++++++++++++++++++++++++++++++------------ test/byFunction.js | 26 ++++++++++++++++++++++++++ test/error.js | 17 +++++++++++++++++ 4 files changed, 76 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 988d699..556b194 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ This object is passed to deepmerge as its [option](https://github.com/TehShrike/ #### editorFunction Type: `function` -The `editorFunction` must have the following signature: `function (json) {}`, and must return JSON object. +The `editorFunction` must have the following signature: `function (json) {}`, and must return JSON object or PromiseLike object with JSON object as value. #### jsBeautifyOptions Type: `object` diff --git a/index.js b/index.js index 89f3941..1cb89f4 100644 --- a/index.js +++ b/index.js @@ -36,6 +36,7 @@ module.exports = function(editor, jsbeautifyOptions, deepmergeOptions) { * create through object and return it */ return through.obj(function(file, encoding, callback) { + var self = this; // ignore it if (file.isNull()) { @@ -50,6 +51,12 @@ module.exports = function(editor, jsbeautifyOptions, deepmergeOptions) { return callback(); } + // when edit fail + var onError = function(err) { + self.emit('error', new PluginError('gulp-json-editor', err)); + callback(); + }; + try { // try to get current indentation var indent = detectIndent(file.contents.toString('utf8')); @@ -60,21 +67,34 @@ module.exports = function(editor, jsbeautifyOptions, deepmergeOptions) { beautifyOptions.indent_char = beautifyOptions.indent_char || (indent.type === 'tab' ? '\t' : ' '); beautifyOptions.beautify = !('beautify' in beautifyOptions && !beautifyOptions.beautify); + // when edit success + var onSuccess = function(json) { + json = JSON.stringify(json); + + // beautify JSON + if (beautifyOptions.beautify) { + json = jsbeautify(json, beautifyOptions); + } + + // write it to file + file.contents = Buffer.from(json); + self.push(file); + callback(); + }; + // edit JSON object and get it as string notation - var json = JSON.stringify(editBy(JSON.parse(file.contents.toString('utf8')))); - - // beautify JSON - if (beautifyOptions.beautify) { - json = jsbeautify(json, beautifyOptions); + var res = editBy(JSON.parse(file.contents.toString('utf8'))); + if (isPromiseLike(res)) { + res.then(onSuccess, onError); + } else { + onSuccess(res); } - - // write it to file - file.contents = Buffer.from(json); } catch (err) { - this.emit('error', new PluginError('gulp-json-editor', err)); + onError(err); } - - this.push(file); - callback(); }); }; + +function isPromiseLike(maybePromise) { + return typeof maybePromise === 'object' && maybePromise !== null && typeof maybePromise.then === 'function'; +} diff --git a/test/byFunction.js b/test/byFunction.js index 9767cfe..7444659 100644 --- a/test/byFunction.js +++ b/test/byFunction.js @@ -172,3 +172,29 @@ it('should multiple properties of JSON object (by function editor)', function(do done(); }); }); + + +it('should modify property asynchronous', function(done) { + + var stream = gulp + .src('test/test.json') + .pipe(json(function(obj) { + obj.version = '2.0.0'; + return Promise.resolve(obj); + })); + + stream.on('data', function(file) { + var expected = + '{\n' + + ' "name": "test object",\n' + + ' "version": "2.0.0",\n' + + ' "nested": {\n' + + ' "name": "nested object",\n' + + ' "version": "1.0.0"\n' + + ' },\n' + + ' "authors": ["tom"]\n' + + '}'; + file.contents.toString().should.eql(expected); + done(); + }); +}); diff --git a/test/error.js b/test/error.js index 77af21c..752f8ee 100644 --- a/test/error.js +++ b/test/error.js @@ -2,6 +2,7 @@ var json = require('../'); var fs = require('fs'); var File = require('vinyl'); var should = require('should'); +var gulp = require('gulp'); it('should raise error when missing option', function(done) { should(function() {json();}).throw('missing "editor" option'); @@ -36,3 +37,19 @@ it('should raise error when streaming input', function(done) { contents: fs.createReadStream('test/test.json'), })); }); + + +it('should raise error when Promise.reject', function(done) { + var msg = 'throw error in async editor'; + gulp + .src('test/test.json') + .pipe( + json(function () { + return Promise.reject(new Error(msg)); + }) + ) + .on('error', function (err) { + err.message.should.equal(msg); + done(); + }); +});