UNPKG

classy-pay-core

Version:

Shared tools used in ClassyPay-related projects

296 lines 10.1 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.unpromisify = exports.runFunctionAfterDelay = exports.sequelizeCloneDeep = exports.recurse = exports.requestWithLogs = exports.redact = exports.omitDeepWithKeys = exports.stringToBoolean = exports.JSONParseBig = exports.normalizeUrl = exports.isJSONString = exports.safeStrConcat = void 0; const axios_1 = __importDefault(require("axios")); const _ = __importStar(require("lodash")); const safeStrConcat = (strings) => { let output = ''; for (const s of strings) { if (s !== null && s !== undefined) { output = output + s; } } return output; }; exports.safeStrConcat = safeStrConcat; const isJSONString = (jsonString) => { try { const o = JSON.parse(jsonString); if (o && typeof o === 'object') { return true; } } catch (e) { } return false; }; exports.isJSONString = isJSONString; const normalizeUrl = (inputUrl) => { const m = inputUrl.match(/^(https?:\/\/)([^:/?#]*)(:[0-9]+)?([^?#]*)?(\?[^?]+)?$/); if (m) { let path = '/'; if (m[4]) { if (!m[4].startsWith('/')) { throw new Error(`Path part of URL didn't start with /`); } path = m[4].replace(/\/\/+/g, '/'); } return (0, exports.safeStrConcat)([ m[1], m[2], m[3], path, m[5], ]); } else { throw new Error(`URL "${inputUrl}" didn't look like a URL and couldn't be normalized`); } }; exports.normalizeUrl = normalizeUrl; const jsonParse = require('json-bigint')({ storeAsString: true }).parse; const JSONParseBig = (json) => require('json-bigint')({ storeAsString: true }).parse(json); exports.JSONParseBig = JSONParseBig; const stringToBoolean = (input, defaultValue = false) => { if (input) { if (_.toLower(input) === 'true') { return true; } const n = parseFloat(input); if (isFinite(n) && !isNaN(n) && n > 0) { return true; } return false; } return defaultValue; }; exports.stringToBoolean = stringToBoolean; const omitDeepWithKeys = (obj, excludeKeys, replacementValue) => { const stackSet = new Set(); const newObj = _.cloneDeep(obj); const omitFn = (value) => { if (!_.isObject(value) || _.isFunction(value) || stackSet.has(value)) { return; } const valueAsRecord = value; excludeKeys.forEach(key => { if (replacementValue && valueAsRecord[key] !== undefined) { valueAsRecord[key] = replacementValue; } else { delete valueAsRecord[key]; } }); stackSet.add(valueAsRecord); for (const key of Object.keys(valueAsRecord)) { omitFn(valueAsRecord[key]); } }; omitFn(newObj); return newObj; }; exports.omitDeepWithKeys = omitDeepWithKeys; const redact = (obj) => (0, exports.omitDeepWithKeys)(obj, [ 'Authorization', 'accountNumber', 'address1', 'address2', 'address3', 'address4', 'city', 'email', 'token', 'province', 'routingNumber', 'state', 'zip', 'processorDetails', 'source', ], '*** REDACTED ***'); exports.redact = redact; const requestWithLogs = async (options, log) => { var _a; let logString; if (log) { const location = options.url; logString = `${(_a = options.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()} ${location}`; log.info((0, exports.redact)({ request: options }), `Request ${logString}`); } let response; let error; try { const retValue = await (0, axios_1.default)(options); response = retValue; return retValue; } catch (e) { if (e instanceof Error) { error = e; throw e; } else { error = new Error('An unknown error occurred'); throw error; } } finally { if (log) { let statusCode = response ? response.status : undefined; if (!statusCode && error && axios_1.default.isAxiosError(error) && error.response) { statusCode = error.response.status; } if (statusCode === 200 && error === undefined) { const toRedactResponse = _.cloneDeep(response); if ((toRedactResponse === null || toRedactResponse === void 0 ? void 0 : toRedactResponse.data) && (0, exports.isJSONString)(JSON.stringify(toRedactResponse.data))) { toRedactResponse.data = JSON.parse(JSON.stringify(toRedactResponse.data)); } log.info((0, exports.redact)({ request: options, response: toRedactResponse }), `Response (Good) ${logString}`); } else { log.error((0, exports.redact)({ request: options, response, error }), `Response (Bad${statusCode ? ' - ' + statusCode : ''}) ${logString}`); } } } }; exports.requestWithLogs = requestWithLogs; const recurse = (input, visitor, options) => { if (input) { const action = visitor('ROOT', input); if (action === 'RECURSE_DEEPER') { _recurseImpl(undefined, input, visitor, options); } } }; exports.recurse = recurse; const _recurseImpl = (parent, input, visitor, options) => { if (Array.isArray(input)) { const inputArray = input; for (let i = 0; i < inputArray.length; i++) { const action = visitor('ARRAY', inputArray[i], i, inputArray); if (action === 'RECURSE_DEEPER') { _recurseImpl(inputArray, inputArray[i], visitor, options); } } } else if (_.isObject(input) && !_.isFunction(input)) { const inputObject = input; const visitNonEnumerableNodes = options ? options.visitNonEnumerableNodes : false; for (const key of visitNonEnumerableNodes ? Object.getOwnPropertyNames(inputObject) : Object.keys(input)) { const action = visitor('OBJECT', inputObject[key], key, inputObject); if (action === 'RECURSE_DEEPER') { _recurseImpl(inputObject, inputObject[key], visitor, options); } } } }; const sequelizeCloneDeep = (input) => { const clonedNodes = new Map(); let clonedRootNode; (0, exports.recurse)(input, (type, value, keyOrIndex, parent) => { let clonedValue; let retval = 'RECURSE_DEEPER'; if (value === undefined || value === null) { clonedValue = value; } else if (keyOrIndex === 'prototype') { return 'STOP'; // prevent prototype pollution } else if (clonedNodes.get(value)) { clonedValue = clonedNodes.get(value); retval = 'STOP'; } else if (value.toJSON) { clonedValue = value.toJSON(); clonedNodes.set(value, clonedValue); retval = 'STOP'; } else { clonedValue = _.clone(value); clonedNodes.set(value, clonedValue); } let clonedParent; if (type === 'ROOT') { clonedNodes.set(value, clonedValue); clonedRootNode = clonedValue; } else { clonedParent = clonedNodes.get(parent); if (!clonedParent) { throw new Error(`Couldn't find cloned parent while recursing`); } clonedParent[keyOrIndex ? keyOrIndex : 0] = clonedValue; } return retval; }); return clonedRootNode; }; exports.sequelizeCloneDeep = sequelizeCloneDeep; const runFunctionAfterDelay = (ms, func) => { return new Promise((resolve, reject) => { setTimeout(async () => { try { const result = await func(); resolve(result); } catch (e) { reject(e); } }, ms); }); }; exports.runFunctionAfterDelay = runFunctionAfterDelay; const unpromisify = async (f, callback) => { let result; let error; try { result = await f(); } catch (e) { error = e; } finally { if (error instanceof Error) { callback(error, result); } else { callback(new Error('An unknown error occurred'), result); } } }; exports.unpromisify = unpromisify; //# sourceMappingURL=utils.js.map