monobank
Version:
Monobank API wrapper
258 lines (200 loc) • 6.79 kB
JavaScript
'use strict';
const resources = require('./resources');
Monobank.DEFAULT_HOST = 'api.monobank.com';
Monobank.DEFAULT_PORT = '443';
Monobank.DEFAULT_BASE_PATH = '/v1/';
Monobank.DEFAULT_API_VERSION = null;
// Use node's default timeout:
Monobank.DEFAULT_TIMEOUT = require('http').createServer().timeout;
Monobank.PACKAGE_VERSION = require('../package.json').version;
Monobank.USER_AGENT = {
bindings_version: Monobank.PACKAGE_VERSION,
lang: 'node',
lang_version: process.version,
platform: process.platform,
publisher: 'monobank',
uname: null,
};
Monobank.USER_AGENT_SERIALIZED = null;
Monobank.MAX_NETWORK_RETRY_DELAY_SEC = 2;
Monobank.INITIAL_NETWORK_RETRY_DELAY_SEC = 0.5;
const APP_INFO_PROPERTIES = ['name', 'version', 'url', 'partner_id'];
const EventEmitter = require('events').EventEmitter;
const utils = require('./utils');
Monobank.MonobankResource = require('./MonobankResource');
Monobank.resources = resources;
function Monobank(key, version) {
if (!(this instanceof Monobank)) {
return new Monobank(key, version);
}
Object.defineProperty(this, '_emitter', {
value: new EventEmitter(),
enumerable: false,
configurable: false,
writeable: false,
});
this.on = this._emitter.on.bind(this._emitter);
this.off = this._emitter.removeListener.bind(this._emitter);
this._api = {
auth: null,
host: Monobank.DEFAULT_HOST,
port: Monobank.DEFAULT_PORT,
basePath: Monobank.DEFAULT_BASE_PATH,
version: Monobank.DEFAULT_API_VERSION,
timeout: Monobank.DEFAULT_TIMEOUT,
agent: null,
dev: false,
maxNetworkRetries: 0,
};
this._prepResources();
this.setApiKey(key);
this.setApiVersion(version);
this.errors = require('./Error');
this.webhooks = require('./Webhooks');
this._prevRequestMetrics = [];
this.setTelemetryEnabled(true);
}
Monobank.errors = require('./Error');
Monobank.webhooks = require('./Webhooks');
Monobank.prototype = {
setHost(host, port, protocol) {
this._setApiField('host', host);
if (port) {
this.setPort(port);
}
if (protocol) {
this.setProtocol(protocol);
}
},
setProtocol(protocol) {
this._setApiField('protocol', protocol.toLowerCase());
},
setPort(port) {
this._setApiField('port', port);
},
setApiVersion(version) {
if (version) {
this._setApiField('version', version);
}
},
setApiKey(key) {
if (key) {
this._setApiField('auth', `Bearer ${key}`);
}
},
setTimeout(timeout) {
this._setApiField(
'timeout',
timeout == null ? Monobank.DEFAULT_TIMEOUT : timeout
);
},
setAppInfo(info) {
if (info && typeof info !== 'object') {
throw new Error('AppInfo must be an object.');
}
if (info && !info.name) {
throw new Error('AppInfo.name is required');
}
info = info || {};
const appInfo = APP_INFO_PROPERTIES.reduce((accum, prop) => {
if (typeof info[prop] == 'string') {
accum = accum || {};
accum[prop] = info[prop];
}
return accum;
}, undefined);
// Kill the cached UA string because it may no longer be valid
Monobank.USER_AGENT_SERIALIZED = undefined;
this._appInfo = appInfo;
},
setHttpAgent(agent) {
this._setApiField('agent', agent);
},
_setApiField(key, value) {
this._api[key] = value;
},
getApiField(key) {
return this._api[key];
},
setClientId(clientId) {
this._clientId = clientId;
},
getClientId() {
return this._clientId;
},
getConstant: (c) => {
return Monobank[c];
},
getMaxNetworkRetries() {
return this.getApiField('maxNetworkRetries');
},
setMaxNetworkRetries(maxNetworkRetries) {
if (
(maxNetworkRetries && typeof maxNetworkRetries !== 'number') ||
arguments.length < 1
) {
throw new Error('maxNetworkRetries must be a number.');
}
this._setApiField('maxNetworkRetries', maxNetworkRetries);
},
getMaxNetworkRetryDelay() {
return this.getConstant('MAX_NETWORK_RETRY_DELAY_SEC');
},
getInitialNetworkRetryDelay() {
return this.getConstant('INITIAL_NETWORK_RETRY_DELAY_SEC');
},
// Gets a JSON version of a User-Agent and uses a cached version for a slight
// speed advantage.
getClientUserAgent(cb) {
if (Monobank.USER_AGENT_SERIALIZED) {
return cb(Monobank.USER_AGENT_SERIALIZED);
}
this.getClientUserAgentSeeded(Monobank.USER_AGENT, (cua) => {
Monobank.USER_AGENT_SERIALIZED = cua;
cb(Monobank.USER_AGENT_SERIALIZED);
});
},
// Gets a JSON version of a User-Agent by encoding a seeded object and
// fetching a uname from the system.
getClientUserAgentSeeded(seed, cb) {
utils.safeExec('uname -a', (err, uname) => {
const userAgent = {};
for (const field in seed) {
userAgent[field] = encodeURIComponent(seed[field]);
}
// URI-encode in case there are unusual characters in the system's uname.
userAgent.uname = encodeURIComponent(uname || 'UNKNOWN');
if (this._appInfo) {
userAgent.application = this._appInfo;
}
cb(JSON.stringify(userAgent));
});
},
getAppInfoAsString() {
if (!this._appInfo) {
return '';
}
let formatted = this._appInfo.name;
if (this._appInfo.version) {
formatted += `/${this._appInfo.version}`;
}
if (this._appInfo.url) {
formatted += ` (${this._appInfo.url})`;
}
return formatted;
},
setTelemetryEnabled(enableTelemetry) {
this._enableTelemetry = enableTelemetry;
},
getTelemetryEnabled() {
return this._enableTelemetry;
},
_prepResources() {
for (const name in resources) {
this[utils.pascalToCamelCase(name)] = new resources[name](this);
}
},
};
module.exports = Monobank;
// expose constructor as a named property to enable mocking with Sinon.JS
module.exports.Monobank = Monobank;