import * as q from "smartq"; import * as through2 from "through2"; import { Transform } from "stream"; export type TExecutionMode = "forEach" | "forFirst" | "atEnd"; export interface IPromiseFunction { (file?, enc?): PromiseLike; } let defaultExport = ( functionsToExecuteArg: IPromiseFunction | IPromiseFunction[], executionModeArg: TExecutionMode = "forEach" ): Transform => { let promiseArray = []; let runFunction = function(functionArg, file, enc) { let returnValue = functionArg(file, enc); if ( typeof returnValue !== "undefined" && typeof returnValue.then !== "undefined" ) { promiseArray.push(returnValue); } }; let checkAndRunFunction = function(file, enc) { if (typeof functionsToExecuteArg === "function") { runFunction(functionsToExecuteArg, file, enc); } else if (Array.isArray(functionsToExecuteArg)) { for (let anyFunction in functionsToExecuteArg) { runFunction(functionsToExecuteArg[anyFunction], file, enc); } } else { throw new Error( "gulp-callfunction: something is strange with the given arguments" ); } return Promise.all(promiseArray); }; let hasExecutedOnce = false; let forEach = function(file, enc, cb) { // the forEach function is called for every chunk switch (executionModeArg) { case "forEach": checkAndRunFunction(file, enc).then(function() { cb(null, file); }); break; case "forFirst": if (hasExecutedOnce) { checkAndRunFunction(file, enc).then(function() { cb(null, file); }); } else { cb(null, file); } hasExecutedOnce = true; break; case "atEnd": cb(); break; default: break; } }; let atEnd = function(cb) { if (executionModeArg === "atEnd") { checkAndRunFunction(null, null).then(function() { cb(); }); } else { cb(); } }; return through2.obj(forEach, atEnd); }; export let forEach = (funcArg: IPromiseFunction) => { return defaultExport(funcArg, "forEach"); }; export let forFirst = (funcArg: IPromiseFunction) => { return defaultExport(funcArg, "forFirst"); }; export let atEnd = (funcArg: IPromiseFunction) => { return defaultExport(funcArg, "atEnd"); }; export default defaultExport;