const _ = require('lodash'), Store = require('tough-cookie').Store, Cookie = require('tough-cookie').Cookie, EXECUTION_EVENT_BASE = 'execution.cookies.', EVENT_STORE_ACTION = 'store', STORE_METHODS = [ 'findCookie', 'findCookies', 'putCookie', 'updateCookie', 'removeCookie', 'removeCookies', 'removeAllCookies', 'getAllCookies' ], FUNCTION = 'function', arrayProtoSlice = Array.prototype.slice; class PostmanCookieStore extends Store { constructor (id, emitter, timers) { super(); this.id = id; // execution identifier this.emitter = emitter; this.timers = timers; } } // Disable CookieJar's *Sync APIs PostmanCookieStore.prototype.synchronous = false; // attach a common handler to all store methods STORE_METHODS.forEach(function (method) { PostmanCookieStore.prototype[method] = function () { const eventName = EXECUTION_EVENT_BASE + this.id; let args, eventId, callback; // fetch all the arguments passed to the method args = arrayProtoSlice.call(arguments); // adjust arguments length based on Store's prototype method // eslint-disable-next-line lodash/path-style args.length = _.get(Store.prototype, [method, 'length'], 0); // move callback/last argument out of arguments // this will be called when timer clears the event callback = args.pop(); // set event for the callback eventId = this.timers.setEvent(function (err, cookies) { if (typeof callback !== FUNCTION) { throw new TypeError('callback is not a function'); } // methods: putCookie, updateCookie, removeCookie, removeCookies, // removeAllCookies // or, onError if (err || !cookies) { return callback(err); } // methods: findCookies, getAllCookies if (Array.isArray(cookies)) { return callback(err, cookies.map(function (cookie) { return Cookie.fromJSON(cookie); // serialize cookie object })); } // method: findCookie callback(err, Cookie.fromJSON(cookies)); }); // finally, dispatch event over the bridge this.emitter.dispatch(eventName, eventId, EVENT_STORE_ACTION, method, args); }; }); module.exports = PostmanCookieStore;