Skip to content

Commit

Permalink
feat(apis): first save ok ✨
Browse files Browse the repository at this point in the history
  • Loading branch information
PierreBrisorgueil committed Mar 17, 2020
1 parent 097056d commit a2676e3
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 76 deletions.
17 changes: 12 additions & 5 deletions lib/helpers/montaineMapping.js → lib/helpers/montaineMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@ const path = require('path');
const _ = require('lodash');

const AppError = require(path.resolve('./lib/helpers/AppError'));
const tricks = require(path.resolve('./lib/helpers/tricks'));

const objectDeepKeys = (obj) => Object.keys(obj).filter((key) => obj[key] instanceof Object).map((key) => objectDeepKeys(obj[key]).map((k) => `${key}.${k}`)).reduce((x, y) => x.concat(y), Object.keys(obj));

/**
* @desc Function to map object to a schema
* @param {object} object - object to map
* @param {schema} schema - schema to generate new object (key value, value = object path)
* @return {object} object - new object generated
*/
const prepareFormat = (object, schema) => {
const result = {};
const keys = objectDeepKeys(schema);
const keys = tricks.objectDeepKeys(schema);
keys.forEach((k) => {
const p = k.split('.');
if (!(/^\d+$/.test(p[p.length - 1])) && !Array.isArray(_.get(schema, k))) {
Expand All @@ -32,8 +37,10 @@ const prepareFormat = (object, schema) => {
return result;
};


exports.mapping = (json, schema) => {
/**
* @desc mapping
*/
exports.map = (json, schema) => {
if (Array.isArray(json) && Array.isArray(schema)) {
return json.map((j) => prepareFormat(j, schema[0]));
} if (typeof example === 'object' && typeof data === 'object') {
Expand Down
107 changes: 107 additions & 0 deletions lib/helpers/montaineSave.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/**
* Module dependencies
*/
const path = require('path');
const _ = require('lodash');

const AppError = require(path.resolve('./lib/helpers/AppError'));
const tricks = require(path.resolve('./lib/helpers/tricks'));

/**
* @desc Function to prepare data for mongo save and historisation, all value became [{updatedAT value }]
* @param {object} object - object to prepare
* @param {date} date - date of update
* @return {object} object - object edited
*/
const prepareSave = (object, date) => {
const result = {};
const keys = tricks.objectDeepKeys(object);
keys.forEach((k) => {
const value = _.get(object, k);
if (k.charAt(0) === '@') _.set(result, k, value);
else if (!Array.isArray(value) && typeof value !== 'object') _.set(result, k, [{ updatedAt: date, value }]);
});
return result;
};

/**
* @desc Function to transform an object in an array of object to blukwrite object in mongo
* @param {object} object - object to prepare
* @return {[object]} [object] - array of action for insert in mongoose
*/
const prepareMongoose = (object) => {
const filter = {};
const arrays = [];
const edits = [];
const keys = tricks.objectDeepKeys(object);
// ini filter base
keys.forEach((k) => {
if (k.charAt(0) === '@') _.set(filter, k, _.get(object, k));
});
// set edits
keys.forEach((k) => {
const value = _.get(object, k);
const paths = k.split('.');
const lastPath = paths[paths.length - 1];
// if we are abd array or in dend of line
if (lastPath !== 'value' && lastPath !== 'updatedAt' && Array.isArray(value)) {
// set base edition
const edit = {
filter: _.clone(filter),
update: {},
};
// if we aren't in end of line, but an intermediate array (mongo dot notation create object if null, not array ...)
if (!value[0].updatedAt) {
edit.filter[k] = { $exists: false };
edit.update.$set = {};
edit.update.$set[`${k}`] = [];
edit.upsert = false;
arrays.push(edit);
} else {
// if we are in end of line, setup update of value if different
edit.filter[`${k}.0.value`] = { $ne: value[0].value };
edit.update.$push = {};
edit.update.$push[`${k}`] = {};
edit.update.$push[`${k}`].$each = [value[0]];
edit.update.$push[`${k}`].$position = -1;
edit.upsert = false;
edits.push(edit);
}
}
});

const init = {
filter,
update: {
$set: filter,
},
upsert: true,
};

return [init, arrays, edits];
};


/**
* @desc saving
*/
exports.prepare = (json, date) => {
if (Array.isArray(json)) {
return json.map((j) => prepareSave(j, date));
} if (typeof example === 'object' && typeof data === 'object') {
return prepareSave(json, date);
}
throw new AppError('Saving failed', { code: 'HELPERS_ERROR' });
};

/**
* @desc saving
*/
exports.save = (json, date) => {
if (Array.isArray(json)) {
return _.flattenDeep(json.map((j) => prepareMongoose(j, date)));
} if (typeof example === 'object' && typeof data === 'object') {
return prepareMongoose(json, date);
}
throw new AppError('Saving failed', { code: 'HELPERS_ERROR' });
};
41 changes: 0 additions & 41 deletions lib/helpers/montaineSaving.js

This file was deleted.

26 changes: 17 additions & 9 deletions lib/helpers/montaineTyping.js → lib/helpers/montaineType.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ const path = require('path');
const _ = require('lodash');

const AppError = require(path.resolve('./lib/helpers/AppError'));

const tricks = require(path.resolve('./lib/helpers/tricks'));

/**
* @desc t
* @param {Object} p - params
* @return {Object} result - params generated
* @desc Function to format data
* @param {data} data - data to edit
* @param {string} action - action to do (funxtion style DATE(), NUMBER() ...)
* @param {object} object - needed in case of function param
* @return {data} data - new data generated
*/
const objectDeepKeys = (obj) => Object.keys(obj).filter((key) => obj[key] instanceof Object).map((key) => objectDeepKeys(obj[key]).map((k) => `${key}.${k}`)).reduce((x, y) => x.concat(y), Object.keys(obj));

const format = (data, action, object) => {
if (!data) throw new AppError('Typing : format data not defined.', { code: 'HELPERS_ERROR' });
if (!action) throw new AppError('Typing : format action not defined.', { code: 'HELPERS_ERROR' });
Expand Down Expand Up @@ -58,9 +58,15 @@ const format = (data, action, object) => {
}
};

/**
* @desc Function to format data in and object based on a schema
* @param {object} object - object to edit
* @param {object} schema - schema with instructions
* @return {object} object - new object generated
*/
const prepareFormat = (object, schema) => {
const result = {};
const keys = objectDeepKeys(object); // get all keys
const keys = tricks.objectDeepKeys(object); // get all keys
keys.forEach((k) => {
const value = _.get(object, k);
if (!Array.isArray(value) && typeof value !== 'object') {
Expand All @@ -78,8 +84,10 @@ const prepareFormat = (object, schema) => {
return result;
};


exports.typing = (json, schema) => {
/**
* @desc typing
*/
exports.type = (json, schema) => {
if (Array.isArray(json) && Array.isArray(schema)) {
return json.map((j) => prepareFormat(j, schema[0]));
} if (typeof example === 'object' && typeof data === 'object') {
Expand Down
6 changes: 6 additions & 0 deletions lib/helpers/tricks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* @desc generate list of all objects keys
* @param {Object} object
* @return {[String]} array of path
*/
exports.objectDeepKeys = (obj) => Object.keys(obj).filter((key) => obj[key] instanceof Object).map((key) => this.objectDeepKeys(obj[key]).map((k) => `${key}.${k}`)).reduce((x, y) => x.concat(y), Object.keys(obj));
22 changes: 8 additions & 14 deletions modules/apis/repositories/apis.repository.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ exports.delete = (api) => Api.deleteOne({ _id: api.id }).exec();
* @param {Object} locations
* @return {Object} locations
*/
exports.import = (collection, items, filters) => {
exports.import = (collection, items) => {
const _schema = new mongoose.Schema({}, {
collection,
strict: false,
Expand All @@ -60,17 +60,11 @@ exports.import = (collection, items, filters) => {
model = mongoose.model(collection, _schema);
}

return model.bulkWrite(items.map((item) => {
const filter = {};
filters.forEach((value) => {
filter[value] = item[value];
});
return {
updateOne: {
filter,
update: item,
upsert: true,
},
};
}));
return model.bulkWrite(items.map((item) => ({
updateOne: {
filter: item.filter,
update: item.update,
upsert: item.upsert,
},
})));
};
16 changes: 9 additions & 7 deletions modules/apis/services/apis.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ const path = require('path');
const _ = require('lodash');

const UserService = require(path.resolve('./modules/users/services/user.service.js'));
const montaineMapping = require(path.resolve('./lib/helpers/montaineMapping'));
const montaineTyping = require(path.resolve('./lib/helpers/montaineTyping'));
const montaineMap = require(path.resolve('./lib/helpers/montaineMap'));
const montaineType = require(path.resolve('./lib/helpers/montaineType'));
const montaineRequest = require(path.resolve('./lib/helpers/montaineRequest'));
const montaineSaving = require(path.resolve('./lib/helpers/montaineSaving'));
const montaineSave = require(path.resolve('./lib/helpers/montaineSave'));
const ApisRepository = require('../repositories/apis.repository');
const HistoryRepository = require('../repositories/history.repository');

Expand Down Expand Up @@ -95,7 +95,7 @@ exports.load = async (api) => {
result.result = request.data;
// Mapping
if (result.result && api.mapping && api.mapping !== '') {
result.mapping = montaineMapping.mapping(result.result, JSON.parse(api.mapping));
result.mapping = montaineMap.map(result.result, JSON.parse(api.mapping));
result.result = result.mapping;
if (!result.mapping) {
result.type = 'error';
Expand All @@ -104,7 +104,7 @@ exports.load = async (api) => {
}
// Typing
if (result.result && result.request.type === 'success' && api.typing && api.typing !== '') {
result.typing = montaineTyping.typing(result.result, JSON.parse(api.typing));
result.typing = montaineType.type(result.result, JSON.parse(api.typing));
result.result = result.typing;
if (!result.typing) {
result.type = 'error';
Expand All @@ -113,8 +113,10 @@ exports.load = async (api) => {
}
// prepare for save
if (result.result) {
result.result = montaineSaving.saving(result.result, start);
await ApisRepository.import(_.camelCase(api.title), result.result, montaineSaving.getKeyForMerge(result.result));
result.prepare = montaineSave.prepare(result.result, start);
result.mongo = montaineSave.save(result.prepare, start);
result.result = result.mongo;
await ApisRepository.import(_.camelCase(api.title), result.result);
}

const history = await HistoryRepository.create(montaineRequest.setScrapHistory(result.request, api, start));
Expand Down

0 comments on commit a2676e3

Please sign in to comment.