UNPKG

fluxible-plugin-fetchr

Version:

A plugin for Fluxible applications to provide an isomorphic interface for RESTful services

176 lines (172 loc) 7.6 kB
/** * Copyright 2014, Yahoo! Inc. * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. */ 'use strict'; var DEFAULT_API_PATH = '/api'; var DEFAULT_XHR_TIMEOUT = 3000; var Fetchr = require('fetchr'); var defaultConstructGetUri = require('fetchr/libs/util/defaultConstructGetUri'); /** * Creates a new fetchr plugin instance with options * @param {Object} options configuration options * @param {String} [options.xhrPath] The path for XHR requests * @param {Function} [options.getXhrPath] Function to dynamically generate xhr path * @param {Number} [options.xhrTimout] Timeout in milliseconds for all XHR requests * @param {Boolean} [options.corsPath] Base CORS path in case CORS is enabled * @param {Object} [options.xhrContext] The xhr context object * @param {Object} [options.contextPicker] The context picker for GET and POST, they must be * lodash pick predicate function with three arguments (value, key, object) * @param {Function} [options.contextPicker.GET] GET context picker * @param {Function} [options.contextPicker.POST] POST context picker * @param {Function} [options.statsCollector] The function will be invoked with 2 arguments: * the actionContext object, which is the action context provided by Fluxible; * the stats object, which contains resource, operation, params (request params), * statusCode, err, and time (elapsed time) * @returns {FetchrPlugin} */ module.exports = function fetchrPlugin(options) { options = options || {}; var xhrPath = options.xhrPath || DEFAULT_API_PATH; var xhrTimeout = options.xhrTimeout || DEFAULT_XHR_TIMEOUT; var corsPath = options.corsPath || null; /** * @class FetchrPlugin */ return { /** * @property {String} name Name of the plugin */ name: 'FetchrPlugin', /** * Called to plug the FluxContext * @method plugContext * @param {Object} contextOptions options passed to the createContext method * @param {Object} contextOptions.req The server request object (only supplied if on server) * @param {Object} contextOptions.xhrContext Context object that will be used for all * XHR calls from the client. This allows persistence of some values between requests * and also CSRF validation. (e.g. { _csrf: 'a3fc2f', device: "tablet" }) * @returns {Object} */ plugContext: function plugContext(contextOptions) { var xhrContext = contextOptions.xhrContext; var currentXhrPath = xhrPath; if (options.getXhrPath) { currentXhrPath = options.getXhrPath(contextOptions); } return { /** * Adds the service CRUD and getServiceMeta methods to the action context * @param actionContext */ plugActionContext: function plugActionContext(actionContext) { var uri; var fetchrOptions = { req: contextOptions.req, xhrPath: currentXhrPath, xhrTimeout: xhrTimeout, corsPath: corsPath, context: xhrContext, contextPicker: options.contextPicker, }; if (typeof options.statsCollector === 'function') { fetchrOptions.statsCollector = function collectFetcherStats(stats) { options.statsCollector(actionContext, stats); }; } var service = new Fetchr(fetchrOptions); actionContext.service = { create: service.create.bind(service), read: service.read.bind(service), update: service.update.bind(service), delete: service.delete.bind(service), constructGetXhrUri: function constructGetXhrUri( resource, params, config ) { config = config || {}; uri = config.cors ? corsPath : currentXhrPath; var getUriFn = config.constructGetUri || defaultConstructGetUri; return getUriFn.call( service, uri, resource, params, config, xhrContext ); }, updateOptions: function (options) { currentXhrPath = options.xhrPath ? options.xhrPath : currentXhrPath; xhrTimeout = options.xhrTimeout ? options.xhrTimeout : xhrTimeout; corsPath = options.corsPath ? options.corsPath : corsPath; service.updateOptions && service.updateOptions(options); }, }; actionContext.getServiceMeta = service.getServiceMeta.bind(service); }, /** * Called to dehydrate plugin options * @method dehydrate * @returns {Object} */ dehydrate: function dehydrate() { return { xhrContext: contextOptions.xhrContext, xhrPath: currentXhrPath, xhrTimeout: xhrTimeout, corsPath: corsPath, }; }, /** * Called to rehydrate plugin options * @method rehydrate * @returns {Object} */ rehydrate: function rehydrate(state) { xhrContext = state.xhrContext; currentXhrPath = state.xhrPath; xhrTimeout = state.xhrTimeout; corsPath = state.corsPath; }, }; }, /** * Registers a service to the manager. Only works on the server! * @method registerService */ registerService: function registerService(service) { Fetchr.registerService(service); }, /** * Get the express middleware. Only works on the server! * @method getMiddleware * @param {Object} [options] Config options to pass to Fetchr middleware. See Fetchr middleware for options. * @returns {Function} */ getMiddleware: function (options) { return Fetchr.middleware(options); }, /** * Provides access to the xhr path being used by the plugin * @method getXhrPath * @returns {String} */ getXhrPath: function getXhrPath() { return xhrPath; }, }; };