UNPKG

braintree

Version:

A library for server-side integrating with Braintree.

322 lines (259 loc) 7.28 kB
"use strict"; const exceptions = require("./exceptions"); class Util { static convertObjectKeysToUnderscores(obj) { let newObj = {}; for (let key in obj) { if (!obj.hasOwnProperty(key)) { continue; } let value = obj[key]; let newKey = Util.toUnderscore(key); if (value instanceof Array) { newObj[newKey] = value.map((item) => typeof item === "object" ? Util.convertObjectKeysToUnderscores(item) : item ); } else if (typeof value === "object") { if (value instanceof Date || value === null) { newObj[newKey] = value; } else { newObj[newKey] = Util.convertObjectKeysToUnderscores(value); } } else { newObj[newKey] = value; } } return newObj; } static convertObjectKeysToCamelCase(obj) { let newObj = {}; for (let key in obj) { if (!obj.hasOwnProperty(key)) { continue; } let value = obj[key]; let newKey = Util.toCamelCase(key); if (value instanceof Array) { newObj[newKey] = value.map((item) => typeof item === "object" ? Util.convertObjectKeysToCamelCase(item) : item ); } else if (typeof value === "object") { if (value instanceof Date || value === null) { newObj[newKey] = value; } else { newObj[newKey] = Util.convertObjectKeysToCamelCase(value); } } else { newObj[newKey] = value; } } return newObj; } // eslint-disable-next-line complexity static convertNodeToObject(obj) { if (typeof obj === "object" && obj["@"]) { if (obj["@"].type === "array") { let newArray = []; Object.keys(obj).forEach((key) => { let value = obj[key]; if (key !== "@") { if (value instanceof Array) { for (let item of value) { newArray.push(this.convertNodeToObject(item)); } } else { newArray.push(this.convertNodeToObject(value)); } } }); return newArray; } else if (obj["@"].type === "collection") { let newObj = {}; Object.keys(obj).forEach((key) => { let value = obj[key]; if (key !== "@") { newObj[this.toCamelCase(key)] = this.convertNodeToObject(value); } }); return newObj; } else if (obj["@"].nil === "true") { return null; } else if (obj["@"].type === "integer") { return parseInt(obj["#"], 10); } else if (obj["@"].type === "boolean") { return obj["#"] === "true"; } return obj["#"]; } else if (obj instanceof Array) { return obj.map((item) => this.convertNodeToObject(item)); } else if (typeof obj === "object" && this.objectIsEmpty(obj)) { return ""; } else if (typeof obj === "object") { let newObj = {}; Object.keys(obj).forEach((key) => { let value = obj[key]; newObj[this.toCamelCase(key)] = this.convertNodeToObject(value); }); return newObj; } return obj; } static objectIsEmpty(obj) { if (Object.keys(obj).length !== 0) { return false; } return true; } static arrayIsEmpty(array) { if (!(array instanceof Array)) { return false; } if (array.length > 0) { return false; } return true; } static toCamelCase(string) { return string.replace(/([\-\_][a-z0-9])/g, (match) => match.toUpperCase().replace("-", "").replace("_", "") ); } static toUnderscore(string) { return string .replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2") .replace(/([a-z])([A-Z])/g, "$1_$2") .toLowerCase(); } static flatten(array) { while (this._containsArray(array)) { array = array.reduce((first, rest) => { first = first instanceof Array ? first : [first]; rest = rest instanceof Array ? this.flatten(rest) : rest; return first.concat(rest); }); } return array; } static merge(obj1, obj2) { for (let key in obj2) { if (!obj2.hasOwnProperty(key)) { continue; } let value = obj2[key]; obj1[key] = value; } return obj1; } static without(array1, array2) { let newArray = []; for (let value of array1) { if (!this._containsValue(array2, value)) { newArray.push(value); } } return newArray; } static withoutIgnoreCaseStyle(array1, array2) { let newArray = []; let array2CamelCased = array2.map((x) => this.toCamelCase(x)); this.convertObjectKeysToCamelCase(array2); for (let value of array1) { if ( !this._containsValue(array2CamelCased, value) && !this._containsValue(array2CamelCased, this.toCamelCase(value)) ) { newArray.push(value); } } return newArray; } static flattenKeys(obj, prefix) { let keys = []; for (let key in obj) { if (!obj.hasOwnProperty(key)) { continue; } let value = obj[key]; if (typeof value === "object") { let keyToPush = null; if (this.isNumeric(key)) { keyToPush = prefix ? prefix : key; } else { keyToPush = prefix ? prefix + "[" + key + "]" : key; } keys.push(Util.flattenKeys(value, keyToPush)); } else if (prefix) { keys.push(prefix + "[" + key + "]"); } else { keys.push(key); } } return this.flatten(keys); } static isNumeric(value) { return !isNaN(value); } // eslint-disable-next-line consistent-return static verifyKeys(keys, obj) { let invalidKeys; let unrecognizedKeys = this.withoutIgnoreCaseStyle( this.flattenKeys(obj), keys.valid ); if (keys.ignore) { invalidKeys = unrecognizedKeys.filter(function (key) { for (let ignoredKey of keys.ignore) { if ( key.indexOf(ignoredKey) === 0 || Util.toCamelCase(key).indexOf(ignoredKey) === 0 ) { return false; } } return true; }); } else { invalidKeys = unrecognizedKeys; } if (invalidKeys.length > 0) { // eslint-disable-next-line new-cap return exceptions.InvalidKeysError( `These keys are invalid: ${invalidKeys.join(", ")}` ); } } static _containsValue(array, element) { return array.indexOf(element) !== -1; } static _containsArray(array) { for (let element of array) { if (element instanceof Array) { return true; } } return false; } static zip(...arrays) { const longestLength = arrays.reduce( (prev, current) => (prev > current.length ? prev : current.length), 0 ); const finalArray = []; let currentIndex = 0; while (currentIndex < longestLength) { const nextArray = []; const i = currentIndex; arrays.forEach((array) => { nextArray.push(array[i]); }); finalArray.push(nextArray); currentIndex++; } return finalArray; } } module.exports = { Util };