Skip to content

Commit

Permalink
Merge ac043ed into d810bd4
Browse files Browse the repository at this point in the history
  • Loading branch information
guillecipri committed Feb 11, 2022
2 parents d810bd4 + ac043ed commit 0d768fc
Show file tree
Hide file tree
Showing 7 changed files with 204 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- Type-def comments were incorporated.

## [6.1.1] - 2021-10-26
### Fixed
Expand Down
61 changes: 61 additions & 0 deletions lib/api-save-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,56 @@ const ApiSaveError = require('./api-save-error');
const ErrorHandler = require('./helpers/error-handler');
const EndpointParser = require('./helpers/endpoint-parser');

/**
* @class representing a ApiSaveData.
* @extends API
*/

/**
* @typedef {Object} ApiSaveError A instance of ApiSaveError class
*/

module.exports = class ApiSaveData extends API {

/**
* @static
* @return {Object}
*/
static get relationshipsParameters() {
return {};
}

/**
* @static
* @return {Function}
*/
static get idStruct() {
return struct.optional('string|number');
}

/**
* @static
* @return {Function}
*/
static get mainStruct() {
return 'object';
}

/**
* @static
* @return {Function}
*/
static get relationshipsStruct() {
return struct.partial({});
}

/**
* Validates the structure of the data to save before processing.
*
* @async
* @returns {void}
* @throws {ApiSaveError} if the validate fails
*/
async validate() {

this._parseEndpoint();
Expand All @@ -47,6 +79,13 @@ module.exports = class ApiSaveData extends API {
}
}

/**
* The process formats, validates, then save the current item.
*
* @async
* @returns {Promise<void>} - The promise of the save.
* @throws {ApiSaveError} if the process fails
*/
async process() {

try {
Expand Down Expand Up @@ -87,6 +126,13 @@ module.exports = class ApiSaveData extends API {
}
}

/**
* Get current item from DB.
*
* @async
* @returns {Object.<string, *>} - The current item.
* @throws {ApiSaveError} if the recordId is not found
*/
async getCurrent() {

if(!this.recordId)
Expand All @@ -98,14 +144,29 @@ module.exports = class ApiSaveData extends API {
return this._currentItem;
}

/**
* Optional method allows you to validate if saving the item is really necessary. Is called after formatting.
*
* @return {boolean} - True if should save, false otherwise.
*/
shouldSave() {
return true;
}

/**
* Check if the current endpoint has relationships.
*
* @return {boolean} - True if has relationships, false otherwise.
*/
hasRelationships() {
return Object.keys(this.dataToSave.relationships).length > 0;
}

/**
* Set the modelName, recordId and parents of API after parsing the endpoint
*
* @returns {void}
*/
_parseEndpoint() {

const { modelName, recordId, parents } = EndpointParser.parse(this.endpoint);
Expand Down
28 changes: 28 additions & 0 deletions lib/api-save-error.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,31 @@
'use strict';

/**
* @class representing a ApiSaveError.
* @extends Error
*/

/**
* @typedef CodesError
* @property {Number} INVALID_REQUEST_DATA
* @property {Number} INVALID_ENTITY
* @property {Number} VALIDATION_ERROR
* @property {Number} DUPLICATED_KEY_ERROR
* @property {Number} INTERNAL_ERROR
*/

/**
* @typedef {Object} Error An instance of Error class
*/

module.exports = class ApiSaveError extends Error {

/**
* Get the error codes
*
* @static
* @returns {CodesError}
*/
static get codes() {

return {
Expand All @@ -14,6 +38,10 @@ module.exports = class ApiSaveError extends Error {

}

/**
* @param {Error} err The details of the error
* @param {CodesError} code The error code
*/
constructor(err, code) {

const message = err.message || err;
Expand Down
14 changes: 14 additions & 0 deletions lib/api-save-main.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
'use strict';

/**
* @class representing a ApiSaveMain.
*/

module.exports = class ApiSaveMain {

/**
* Constructor
* @param {Object} apiInstance - The API instance.
*/
constructor(apiInstance) {
this.apiInstance = apiInstance;
}

/**
* Save the current item (insert or update).
*
* @async
* @returns {Promise<void>} - The promise of the save.
*/
async process() {

const dataToSave = {
Expand Down
59 changes: 59 additions & 0 deletions lib/api-save-relationships.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,44 @@

const isEqual = require('lodash.isequal');

/**
* @class representing a ApiSaveRelationships.
*/

class ApiSaveRelationships {

/**
* Constructor
*
* @param {Object} apiInstance
* @param {string|number} mainId
* @param {Boolean} isNewRecord
*/
constructor(apiInstance, mainId, isNewRecord) {
this.apiInstance = apiInstance;
this.mainId = mainId;
this.isNewRecord = isNewRecord;
}

/**
* Save all items relationships.
*
* @returns {<Promise>} - The promise of the save.
*/
process() {

const promises = Object.keys(this.apiInstance.dataToSave.relationships).map(relationship => this.save(relationship));

return Promise.all(promises);
}

/**
* Save the current item.
*
* @param {string} relationship - The relationship to save.
* @returns {Boolean} - Boolean if the save was successful.
* @throws an Error when the relationshipParameters is not defined.
*/
save(relationship) {

const relationshipParameters = this.getRelationshipParameters(relationship);
Expand All @@ -30,6 +53,13 @@ class ApiSaveRelationships {
return this.insert(relationship, relationshipParameters);
}

/**
* Formatting the relationships and relationshipParameters to insert.
*
* @param {string} relationship
* @param {Object} relationshipParameters
* @returns {Boolean|undefined} - The relationships to insert.
*/
insert(relationship, relationshipParameters) {

const { modelClass: ModelClass } = relationshipParameters;
Expand All @@ -44,6 +74,14 @@ class ApiSaveRelationships {
return model.multiInsert(relationshipsToSave);
}

/**
* Insert and remove the relationships.
*
* @async
* @param {string} relationship
* @param {Object} relationshipParameters
* @returns {Array<Promise>} - Array promise of the insert and remove.
*/
async insertAndRemove(relationship, relationshipParameters) {

const { modelClass: ModelClass, mainIdentifierField } = relationshipParameters;
Expand All @@ -63,10 +101,23 @@ class ApiSaveRelationships {
return Promise.all([removePromise, insertPromise]);
}

/**
* Get relationship parameters.
*
* @param {string} relationship
* @returns {Object} - The relationship parameters.
*/
getRelationshipParameters(relationship) {
return this.apiInstance.constructor.relationshipsParameters[relationship];
}

/**
* Formatting the relationships and relationshipParameters before insert.
*
* @param {string} relationship
* @param {Object} relationshipParameters
* @returns {Array} - The relationships to insert.
*/
_formatRelationshipsToInsert(relationship, relationshipParameters) {

const { mainIdentifierField, secondaryIdentifierField } = relationshipParameters;
Expand All @@ -87,6 +138,14 @@ class ApiSaveRelationships {
});
}

/**
* Split the relationships to insert and remove.
*
* @param {Array<string>} currentRelationships
* @param {Array<string>} relationshipsToSave
* @param {Object} relationshipParameters
* @returns {Object} - The insert and remove data.
*/
_splitRelationshipsToUpdate(currentRelationships, relationshipsToSave, relationshipParameters) {

if(!currentRelationships.length) {
Expand Down
33 changes: 33 additions & 0 deletions lib/api-save-validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,19 @@ const path = require('path');

const ApiSaveError = require('./api-save-error');

/**
* @class representing a ApiSaveValidator.
*/

/**
* @typedef {Object} ApiSaveError A instance of ApiSaveError class
*/
class ApiSaveValidator {

/**
* @static
* @return {Function}
*/
get struct() {
return {
id: this.apiInstance.constructor.idStruct,
Expand All @@ -15,10 +26,20 @@ class ApiSaveValidator {
};
}

/**
* Constructor.
* @param {Object} apiInstance
*/
constructor(apiInstance) {
this.apiInstance = apiInstance;
}

/**
* Validates the struct data.
*
* @returns {object} - The data to save.
* @throws {ApiSaveError} if the validate fails
*/
validateData() {

const validationStruct = this.struct;
Expand All @@ -41,6 +62,12 @@ class ApiSaveValidator {
}
}

/**
* Validate model.
*
* @returns {object} - The model instance.
* @throws {ApiSaveError} if the validate model fails
*/
validateModel() {
try {
return this._getModelInstance(path.join(process.cwd(), process.env.MS_PATH || '', 'models', this.apiInstance.modelName));
Expand All @@ -49,6 +76,12 @@ class ApiSaveValidator {
}
}

/**
* Get model instance.
*
* @param {*} modelPath
* @returns {object} - The model instance.
*/
_getModelInstance(modelPath) {

// eslint-disable-next-line global-require, import/no-dynamic-require
Expand Down

0 comments on commit 0d768fc

Please sign in to comment.