UNPKG

fluro

Version:

Promise based HTTP Fluro client for the browser and node.js

1,266 lines (963 loc) 41.2 kB
import _ from 'lodash'; import axios from 'axios'; const CancelToken = axios.CancelToken; import FluroContentListService from '../services/FluroContentListService'; import { Cache, } from 'axios-extensions'; /////////////////////////////////////////////////// /** * Creates a new FluroContent instance. * This module provides a number of helper functions for Creating, Reading, Updating and Deleting content via the Fluro API * @alias content * @constructor * @hideconstructor * @param {FluroCore} fluro A reference to the parent instance of the FluroCore module. This module is usually created by a FluroCore instance that passes itself in as the first argument. */ var FluroContent = function(fluro) { if (!fluro.api) { throw new Error(`Can't Instantiate FluroContent before FluroAPI exists`); } //Keep track of any refresh requests var inflightRefreshRequest; /////////////////////////////////////////////////// var service = {} /////////////////////////////////////////////////// /** * Runs a search from the Fluro server and returns the results * @alias content.search * @param {String} terms The keywords to search for * @param {Object} options Extra Configuration and options for how to search the database and how to render the results * @param {Object} options.limit How many results should be returned. Defaults to 10 * @param {Array} options.types Specify types or definition names for which items should be searched for * @param {Boolean} options.showQuery If true will return the query used to search instead of the search results themselves * @return {Array} An array of content items that match the search, if options.types is specified will be a nested array of results for each type * * @example * fluro.content.search('Wonder', {limit:5, types:['song', 'album', 'tag']}).then(function(results) { * //Will return a nested array with up to 5 results for each type * //[{_type:'Song', results:[{title:"Wonder"...}]}, {_type:'Album', results:[{title:"Wonder"...}]}] * }) * * fluro.content.search('Wonder', {limit:5}).then(function(results) { * //Will return an array of up to 5 items the user has access to view that match the search terms * //[{title:"Wonder", _type:'article', definition:'song'...}, {title:"Wonder", _type:'article', definition:'album'...}] * }) */ ///////////////////////////////////////////////// var currentSearch; ///////////////////////////////////////////////// service.search = function(terms, params, config) { if (!params) { params = {}; } if (!params.limit) { params.limit = 10; } ///////////////////////////////////////////////// if (currentSearch) { // cancel the request (the message parameter is optional) currentSearch.cancel('Operation canceled by the user.'); } ///////////////////////////////////////////////// currentSearch = CancelToken.source(); ///////////////////////////////////////////////// return new Promise(function(resolve, reject) { if (!terms || !terms.length) { return resolve([]); } if (!config) { config = {}; } config.params = params; config.cancelToken = currentSearch.token; // var requestOptions = { // params: options, // cancelToken: currentSearch.token, // } ///////////////////////////////////////////// //Retrieve the query results fluro.api.get(`/content/search/${terms}`, config).then(function(res) { resolve(res.data); }).catch(function(thrown) { if (axios.isCancel(thrown)) { // //console.log('Request canceled', thrown.message); } else { // handle error } }); }); } /////////////////////////////////////////////////// /** * Retrieves a specific definition or data type * @alias content.type * @param {String} definitionName The defined type or definition name to retrieve * @param {Object} options Extra Configuration and options for how to search the database and how to render the results * @return {Promise} A promise that will resolve with the definition * * @example * fluro.content.type('song', options, config).then(function(definition) { * //Will return the definition * }) */ var typePromise = {};; var typeCacheable = true; ///////////////////////////////////////////////// service.type = function(definitionName, params) { if (!params) { params = {}; } if (!definitionName) { throw Error('No definition name was provided'); } ///////////////////////////////////////////////// //If we are already requesting this definition if (typePromise[definitionName] && params.cache !== false) { return typePromise[definitionName]; } //Create a new promise typePromise[definitionName] = new Promise(function(resolve, reject) { // if (!config) { // config = {}; // } // config.params = params; // var requestOptions = { // params: options, // cancelToken: currentMentionSearch.token, // } ///////////////////////////////////////////// //Retrieve the definition from the server and send it back to //the user fluro.api.get(`/defined/${definitionName}`) .then(function(res) { // console.log('CONTENT GET', definitionName, res.data); resolve(res.data); typeCacheable = true; }).catch(function(err) { reject(err); typeCacheable = false; }); }); ///////////////////////////////////////////////// return typePromise[definitionName]; } /////////////////////////////////////////////////// /** * Runs a search from the Fluro server for a specific mentionable user * @alias content.mention * @param {String} mentionID the Name or Mention ID of the persona to search for * @param {Object} options Extra Configuration and options for how to search the database and how to render the results * @param {Object} config Optional HTTP Request Configuration * @param {Integer} options.limit Extra Configuration and options for how to search the database and how to render the results * @param {Integer} options.managed Search for managed personas instead of Global Fluro user personas * @return {Array} An array of personas who can be mentioned * * @example * fluro.content.mention('john.smith', {limit:5}, config).then(function(results) { * //Will return a nested array with up to 5 personas * }) */ ///////////////////////////////////////////////// var currentMentionSearch; ///////////////////////////////////////////////// service.mention = function(terms, params, config) { if (!params) { params = {}; } if (!params.limit) { params.limit = 5; } ///////////////////////////////////////////////// if (currentMentionSearch) { // cancel the request (the message parameter is optional) currentMentionSearch.cancel('Operation canceled by the user.'); } ///////////////////////////////////////////////// currentMentionSearch = CancelToken.source(); ///////////////////////////////////////////////// return new Promise(function(resolve, reject) { if (!terms || !terms.length) { return resolve([]); } if (!config) { config = {}; } config.params = params; config.cancelToken = currentMentionSearch.token; // var requestOptions = { // params: options, // cancelToken: currentMentionSearch.token, // } ///////////////////////////////////////////// //Retrieve the query results fluro.api.get(`/mention/${terms}`, config).then(function(res) { resolve(res.data); }).catch(function(thrown) { if (axios.isCancel(thrown)) { // //console.log('Request canceled', thrown.message); } else { // handle error } }); }); } /////////////////////////////////////////////////// /** * A helper function for retrieving the results of a specified query * @alias content.query * @param {String} queryID The id of the query you want to run * @param {Object} options The options for the query * @param {Object} options.params The query string parameters for the query that will be mapped ?one=value&two=value * @param {Object} options.variables Any query variables you wish to inject each key will be mapped ?variables[key]=value * @return {Promise} A promise that will be resolved with the results or an error */ service.query = function(queryID, options, requestOptions) { //Get as just a query queryID = fluro.utils.getStringID(queryID); if (!options) { options = {} } if (!requestOptions) { requestOptions = { params: {}, } } return new Promise(function(resolve, reject) { //If there are query string parameters if (options.params) { requestOptions.params = options.params; } ///////////////////////////////////////////// if (options.variables) { var variableParams = _.reduce(options.variables, function(set, value, key) { set[`variables[${key}]`] = value; return set; }, {}) //Add it to our parameters _.assign(requestOptions.params, variableParams); } ///////////////////////////////////////////// //Retrieve the query results fluro.api.get(`/content/_query/${queryID}`, requestOptions).then(function(res) { resolve(res.data); }, reject); }) } /////////////////////////////////////////////////// /** * This function returns a single populated item by providing its _id * @alias content.get * @param {String} id The item's _id * @param {Object} params Extra query string parameters for the request * @return {Promise} A promise that will be resolved with the item or an error * @example * * //Retrieve just the title for item '5be504eabf33991239599d63' * fluro.content.get('5be504eabf33991239599d63', {select:'title'}) */ service.get = function(id, params, requestOptions) { if (!requestOptions) { requestOptions = {}; } ///////////////////////////////////// //Ensure it's a simple single ID id = fluro.utils.getStringID(id); ///////////////////////////////////// if (!params) { params = {} } ///////////////////////////////////// return new Promise(function(resolve, reject) { //If there are query string parameters if (params) { requestOptions.params = params; } ///////////////////////////////////////////// // //console.log('REQUEST OPTIONS', requestOptions); //Retrieve the query results fluro.api.get(`/content/get/${id}`, requestOptions) .then(function(res) { resolve(res.data); }, reject); }) } /////////////////////////////////////////////////// /////////////////////////////////////////////////// /** * This function returns a single populated item by providing its _external id * @alias content.external * @param {String} externalID The item's _external id property * @param {Object} params Extra query string parameters for the request * @return {Promise} A promise that will be resolved with the item or an error * @example * * //Retrieve just the title for item with external id that matches '5be504-eabf33991-239599-d63' * fluro.content.external('5be504-eabf33991-239599-d63', {select:'title'}) */ service.external = function(id, params, requestOptions) { if (!requestOptions) { requestOptions = {}; } ///////////////////////////////////// if (!params) { params = {} } return new Promise(function(resolve, reject) { //If there are query string parameters if (params) { requestOptions.params = params; } ///////////////////////////////////////////// //Retrieve the query results fluro.api.get(`/content/external/${id}`, requestOptions).then(function(res) { resolve(res.data); }, reject); }) } /////////////////////////////////////////////////// /** * This function returns a single populated item by providing its slug * @alias content.slug * @param {String} slug The item's slug value * @param {Object} params Extra query string parameters for the request * @return {Promise} A promise that will be resolved with the item or an error * @example * * //Retrieve just the title for item with the slug 'my-article' * fluro.content.slug('my-article', {select:'title'}) */ service.slug = function(id, params, requestOptions) { if (!requestOptions) { requestOptions = {} } if (!params) { params = {} } return new Promise(function(resolve, reject) { //If there are query string parameters if (params) { requestOptions.params = params; } ///////////////////////////////////////////// //Retrieve the query results fluro.api.get(`/content/slug/${id}`, requestOptions).then(function(res) { resolve(res.data); }, reject); }) } /////////////////////////////////////////////////// /** * A helper function for retrieving the results of a dynamic query * @alias content.retrieve * @param {Object} criteria The query criteria * @param {Object} options Extra options and parameters * @return {Promise} A promise that will be resolved with the results or an error * @example * * //Find all events that have a status of active or archived where the endDate is greater than or equal to now and return the titles * fluro.content.retrieve({_type:'event', status:{$in:['active', 'archived']}, endDate:{$gte:"date('now')"}}}, {select:'title'}) */ service.retrieve = function(criteria, params, requestOptions) { if (!params) { params = {} } if (!requestOptions) { requestOptions = {} } return new Promise(function(resolve, reject) { //If there are query string parameters if (params) { requestOptions.params = params; } ///////////////////////////////////////////// //Retrieve the query results fluro.api.post(`/content/_query`, criteria, requestOptions).then(function(res) { resolve(res.data); }, reject); }) } /////////////////////////////////////////////////// /** * This function returns a list of related items * That either reference the specified item or are referenced by the provided item * @alias content.related * @param {String} id The item to find related content for * @param {Object} params Extra query string parameters for the request * @return {Promise} A promise that will be resolved with an array of related items * @example * * //Retrieve some related items for '5be504eabf33991239599d63' * fluro.content.related('5be504eabf33991239599d63', {select:'title'}) */ service.related = function(id, params, requestOptions) { id = fluro.utils.getStringID(id); if (!id) { throw Error(`No id specified ${id}`); } if (!requestOptions) { requestOptions = {} } if (!params) { params = {} } return new Promise(function(resolve, reject) { //If there are query string parameters if (params) { requestOptions.params = params; } var criteria = { _references: id, } // service.retrieve(criteria, requestOptions).then(resolve, reject); // ///////////////////////////////////////////// //Retrieve the query results fluro.api.get(`/content/related/${id}`, requestOptions).then(function(res) { resolve(res.data); }, reject); }) } /////////////////////////////////////////////////// /** * This function returns an interaction definition via the public 'form' API endpoint * This will only result successfully if the definition requested has the definition of 'form' and has the status of 'active' * @alias content.form * @param {String} id The id of the form to retrieve * @param {Object} options Extra options for the request * @param {Object} options.testing Whether to load the form in testing mode or not * @return {Promise} A promise that will be resolved with the form or an error * @example * * //Retrieve a form ('58dca23c21428d2d045a1cf7') in testing mode * fluro.content.form('58dca23c21428d2d045a1cf7', {testing:true}) */ service.form = function(id, options, requestOptions) { id = fluro.utils.getStringID(id); if (!id) { throw Error(`No id specified ${id}`); } if (!requestOptions) { requestOptions = {} } if (!options) { options = {} } if (options.requestOptions) { requestOptions = options.requestOptions; } return new Promise(function(resolve, reject) { //If there are query string parameters // if (params) { // requestOptions.params = params; // } // service.retrieve(criteria, requestOptions).then(resolve, reject); // ///////////////////////////////////////////// // //console.log('request form', id, requestOptions); //Retrieve the query results fluro.api.get(`/form/${id}`, requestOptions).then(function(res) { // //console.log('resolve form', res.data); resolve(res.data); }, reject); }) } /////////////////////////////////////////////////// /** * This function makes it easy to submit form interactions via the Fluro API * @alias content.submitInteraction * @param {String} definitionName the definition of the form you want to submit eg. 'supportRequest' or 'contactUs'... * @param {Object} data The interaction data to submit * @param {Object} options Extra options for the request * @param {Object} options.reply The id of the post to reply to (If threaded conversation) * @return {Promise} A promise that will be resolved with an array of related items * @example * * //Retrieve some related items for '5be504eabf33991239599d63' * fluro.content.submitInteraction('5be504eabf33991239599d63', 'comment', {data:{customField:'My message'}}, {reply:'5be504eabf33991239599d63'}) */ service.submitInteraction = function(type, submission, options) { //console.log('SUBMIT INTERACTION') if (!options) { options = {} } return new Promise(function(resolve, reject) { var requestOptions = options; ///////////////////////////////////////////// //console.log('SUBMISSION ACTIONS', requestOptions); //Retrieve the query results fluro.api.post(`/interact/${type}`, submission, requestOptions) .then(function(res) { resolve(res.data); }, reject); }) } /////////////////////////////////////////////////// /** * This function makes it easy to create and attach a post to a specified piece of fluro content * @alias content.submitPost * @param {String} target The ID of the item to attach this post to * @param {String} definitionName the definition type of the post you want to create eg. 'note' or 'comment'... * @param {Object} data The post content to create * @param {Object} options Extra options for the request * @param {Object} options.reply The id of the post to reply to (If threaded conversation) * @return {Promise} A promise that will be resolved with an array of related items * @example * * //Retrieve some related items for '5be504eabf33991239599d63' * fluro.content.submitPost('5be504eabf33991239599d63', 'comment', {data:{customField:'My message'}}, {reply:'5be504eabf33991239599d63'}) */ service.submitPost = function(id, type, body, options) { id = fluro.utils.getStringID(id); if (!id) { throw Error(`No target specified ${id}`); } if (!options) { options = {} } return new Promise(function(resolve, reject) { var requestOptions = options.requestOptions || { // params: {} } // ///////////////////////////////////////////// //Retrieve the query results fluro.api.post(`/post/${id}/${type}`, body, requestOptions) .then(function(res) { resolve(res.data); }, reject); }) } /////////////////////////////////////////////////// /** * This function makes it easy to retrieve the current thread of posts attached to a specific * item * @alias content.thread * @param {String} target The ID of the item to attach this post to * @param {String} definitionName the definition type of the post you want to create eg. 'note' or 'comment'... * @param {Object} data The post content to create * @param {Object} options Extra options for the request * @param {Object} options.reply The id of the post to reply to (If threaded conversation) * @return {Promise} A promise that will be resolved with an array of related items * @example * * //Retrieve the current post thread of all 'comments' attached to a specific content * fluro.content.thread('5be504eabf33991239599d63', 'comment', {data:{customField:'My message'}}, {reply:'5be504eabf33991239599d63'}) */ service.thread = function(id, type, options) { id = fluro.utils.getStringID(id); if (!id) { throw Error(`No target specified ${id}`); } if (!options) { options = {} } return new Promise(function(resolve, reject) { var requestOptions = { // params: {} } // ///////////////////////////////////////////// //Retrieve the query results fluro.api.get(`/post/${id}/${type}`, requestOptions) .then(function(res) { resolve(res.data); }, reject); }) } /////////////////////////////////////////////////// /** * This function makes it easy to retrieve all distinct values for a specified field key * for a specified subset of items from the server, for instance if you wanted to retrieve all possible 'firstName' values from * a selection of content ids * @alias content.values * @param {Array} ids The ids you want to retrieve values for * @param {String} key the key of the field you want to retrieve the values for * @return {Promise} A promise that will be resolved with an array of possible values * @example * * * fluro.content.values(['5be504eabf33991239599d63'], 'firstName').then(function(values) { * //Would return ['Frank', 'Lucy', 'Marissa'] * }) */ service.values = function(ids, key, options) { ids = fluro.utils.arrayIDs(ids); // if (!ids | !ids.length ) { // throw Error(`No ids specified ${ids}`); // } if (!key | !key.length) { throw Error(`No key specified `); } if (!options) { options = {} } return new Promise(function(resolve, reject) { var payload = { ids, key, } ///////////////////////////////////////////// var url = `/content/distinct/values`; if (options.type) { url = `/content/${options.type}/distinct/values`; } ///////////////////////////////////////////// //Retrieve the query results return fluro.api.post(url, payload, options) .then(function(res) { resolve(_.orderBy(res.data, function(entry) { return entry.title || entry; })); }, reject); }) } service.createDuplicate = function(populatedItem) { var definedType = populatedItem.definition || populatedItem._type; var newItem = JSON.parse(JSON.stringify(populatedItem)); //////////////////////////////////////////// delete newItem._id; delete newItem.slug; delete newItem.author; delete newItem.managedAuthor; delete newItem.__v; delete newItem.created; delete newItem.updated; delete newItem.updatedBy; delete newItem.stats; delete newItem.privateDetails; delete newItem._external; delete newItem.apikey; //////////////////////////////////////////// switch (newItem._type) { case 'event': //Clear out other bits newItem.plans = []; newItem.assignments = []; break; case 'mailout': newItem.state = 'ready'; newItem.subject = newItem.title; newItem.title = newItem.title + ' Copy'; delete newItem.publishDate; break; case 'plan': newItem.startDate = null; break; case 'persona': newItem.user = null; newItem.collectionEmail = ''; newItem.username = ''; newItem.firstName = ''; newItem.lastName = ''; break; } newItem.status = 'active'; //////////////////////////////////////////// newItem.realms = []; delete newItem.account; return Promise.resolve(newItem); } /////////////////////////////////////////////////// /** * This function creates an instance of a FluroContentListService * this then becomes a service that can be used to retrieve filtered data from the server * @alias content.list * @param {String} typeName The type or definition name of the content you want to retrieve * @param {Object} options Extra options for creating the service * @param {Object} options.criteria The filter criteria for specifying which content items should be returned * @param {Object} options.criteria.sort The sorting configuration for the results * @param {Boolean} options.criteria.allDefinitions Whether to include all defined types if a basic type is used as the typeName * @param {Object} options.criteria.filter the fluro filter configuration for filtering returned results * @param {String} options.criteria.search A basic keyword search for filtering results * @param {Date} options.criteria.startDate Used in conjunction with endDate to crop results to a relevant date period * @param {Date} options.criteria.endDate Used in conjunction with startDate to crop results to a relevant date period * @param {Object} options.perPage The number of items to retrieve per page * @param {Object} options.pageIndex The starting page to load from the list * @param {Object} options.cumulative Whether new page items should append to the results or replace the results * @param {Object} options.cacheKey A cache id that can be used to refresh cached results * @return {Object} A new instance of a FluroContentListService * @example * * //How to sort the results * var sort = { * key:'title', * direction:'asc', * type:'string', * } * * //If you want to filter by search keywords * var search = 'Any keywords you want to search for' * * //If you want to crop results to within a certain timeframe * var startDate;// = new Date(); * var endDate;// = new Date() * * //For more complex AND/OR filtering * var filter = { * operator:'and', * filters:[ * { * key:'status', * comparator:'in', * values:['active'], * } * ] * } * * var criteria = { * search, * sort, * startDate, * endDate, * filter, * } * * var dataBucket = fluro.content.list('event', { * perPage: 2, * criteria, * }); * * var isLoading = dataBucket.loading; * var allItems = dataBucket.items; * var pageItems = dataBucket.page; * var currentPage = dataBucket.pageIndex; * dataBucket.nextPage(); * dataBucket.previousPage(); * dataBucket.reloadCurrentPage(); * dataBucket.addEventListener('items', function(results) {}); * dataBucket.addEventListener('error', function(err) { console.log('an error occurred')}); * dataBucket.addEventListener('totalPages', function() { console.log('the number of pages changed')}); * dataBucket.addEventListener('loadingFilter', function() { console.log('filter is reloading')}); * dataBucket.addEventListener('loadingPage', function() { console.log('the page is reloading')}); * dataBucket.addEventListener('page', function() { console.log('the current page was updated')}); */ service.list = function(typeName, options) { return new FluroContentListService(typeName, fluro, options); } /////////////////////////////////////////////////// /** * This function makes it easy to retrieve a large filtered list of content matching certain criteria * Only the relevant fields will be returned that allows you to paginate and populate content with the * fluro.content.getMultiple() function * for more information please see the REST API endpoint documentation here (https://developers.fluro.io/#filter-content) * @alias content.filter * @param {String} typeName The type or definition name of the content you want to retrieve * @param {Object} criteria The criteria used to filter the results * @return {Promise} A promise that will be resolved with an array of all results * @example * * //How to sort the results * var sort = { * key:'title', * direction:'asc', * type:'string', * } * * //If you want to filter by search keywords * var search = 'Any keywords you want to search for' * * //If you want to crop results to within a certain timeframe * var startDate;// = new Date(); * var endDate;// = new Date() * * //For more complex AND/OR filtering * var filter = { * operator:'and', * filters:[ * { * key:'status', * comparator:'in', * values:['active'], * } * ] * } * * var criteria = { * search, * sort, * startDate, * endDate, * filter, * } * * fluro.content.filter('event', criteria) * .then(function(results) { * //Returns all results with the basic fields * }) */ service.filter = function(typeName, criteria) { return new Promise(function(resolve, reject) { return fluro.api.post(`/content/${typeName}/filter`, criteria) .then(function(res) { return resolve(res.data); }) .catch(reject); }) } /////////////////////////////////////////////////// /** * This function makes it easy to retrieve the full content items for a specified selection of ids * @alias content.getMultiple * @param {String} typeName The type or definition name of the content you want to retrieve * @param {Array} ids The ids of the content you want to retrieve * @param {Object} options extra options for the request * @param {Array} options.select specify fields you want to retrieve for the items. If blank will return the full object * @return {Promise} A promise that will be resolved with an array of possible keys * @example * * * fluro.content.getMultiple(['5be504eabf33991239599d63', '5be504eabf33721239599d83']) .then(function(items) { * //Returns the full content items * }) */ service.getMultiple = function(typeName, ids, options) { if(!options) { options = {}; } //Ensure the ids are actually ids ids = fluro.utils.arrayIDs(ids); //console.log('posted', ids); return new Promise(function(resolve, reject) { fluro.api.post(`/content/${typeName}/multiple`, { ids, select: options.select ? _.uniq(options.select) : undefined, //populateAll: true, limit: ids.length, //appendContactDetails, //appendAssignments, //appendFullFamily, // cancelToken: currentPageItemsRequest.token, }) .then(function(res) { resolve(res.data); }) .catch(reject); }) } /////////////////////////////////////////////////// /** * This function makes it easy to retrieve all distinct keys for a specified selection of ids * @alias content.keys * @param {Array} ids The ids you want to retrieve keys for * @param {Object} options extra options and query parameters for the http request * @return {Promise} A promise that will be resolved with an array of possible keys * @example * * * fluro.content.keys(['5be504eabf33991239599d63']).then(function(values) { * //Would return ['firstName', 'lastName', 'title', 'tags', 'realms'] * }) */ service.keys = function(ids, options) { ids = fluro.utils.arrayIDs(ids); if (!ids | !ids.length) { throw Error(`No ids specified ${ids}`); } if (!options) { options = {} } return new Promise(function(resolve, reject) { var payload = { ids, } ///////////////////////////////////////////// var url = `/content/distinct/keys`; if (options.type) { url = `/content/${options.type}/distinct/keys`; } ///////////////////////////////////////////// //Retrieve the query results return fluro.api.post(url, payload, options) .then(function(res) { resolve(res.data); }, reject); }) } /////////////////////////////////////////////////// /** * This function creates a clean copy of a specified content item * @alias content.duplicate * @param {Object} item The ID or object representing the item you want to duplicate * @return {Promise} A promise that will be resolved with a cleaned duplicate of the original item * @example * * * fluro.content.duplicate({_id:'5be504eabf33991239599d63'}) * .then(function(freshItem) { * //Fresh item is a cleaned duplicate of the original item * }) */ service.duplicate = function(item, options) { if (!options) { options = {}; } /////////////////////////////////////// var itemID = fluro.utils.getStringID(item); return new Promise(function(resolve, reject) { //Load the proper thing service.get(itemID) .then(function(populatedItem) { var definedType = populatedItem.definition || populatedItem._type; var newItem = JSON.parse(JSON.stringify(populatedItem)); //////////////////////////////////////////// //Remove the bits and pieces delete newItem._id; delete newItem.slug; delete newItem.author; delete newItem.managedAuthor; delete newItem.__v; delete newItem.created; delete newItem.updated; delete newItem.updatedBy; delete newItem.stats; delete newItem.privateDetails; delete newItem._external; delete newItem.apikey; //////////////////////////////////////////// if (options.customise) { //Keep the definition name } else { delete newItem.definitionName; //console.log('Dupliacate', newItem) } //////////////////////////////////////////// switch (newItem._type) { case 'event': //Clear out other bits newItem.plans = []; newItem.assignments = []; break; case 'mailout': newItem.state = 'ready'; newItem.subject = newItem.title; newItem.title = newItem.title + ' Copy'; delete newItem.publishDate; break; case 'plan': newItem.startDate = null; break; case 'persona': newItem.user = null; newItem.collectionEmail = ''; newItem.username = ''; newItem.firstName = ''; newItem.lastName = ''; break; } //Set the new item as active newItem.status = 'active'; //////////////////////////////////////////// var accountID = fluro.utils.getStringID(newItem.account); var userAccountID = fluro.utils.getStringID(populatedItem.account); if (userAccountID != accountID) { newItem.realms = []; } delete newItem.account; //////////////////////////////////////////// return resolve(newItem); }) .catch(reject) }) } ////////////////////////////////////// return service; } export default FluroContent;