Bug Fixes

This commit is contained in:
Luis Fernando Molina committed 2020-02-09 16:35:17 +01:00
1 parent 82bc086e92
commit b1af6e078c
131 files changed
+8597 -1930

No files matched your search

+1 -1
View File
@@ -391,7 +391,7 @@ function newTimeMachine () {
}
function panelPhysics () {
if (thisObject.container.frame.isInViewPort()) {
if (thisObject.container.frame.isInViewPort() && canvas.chartSpace.viewport.zoomTargetLevel > 10) {
canvas.panelsSpace.makeVisible(thisObject.payload.node.id, 'Layers Panel')
} else {
canvas.panelsSpace.makeInvisible(thisObject.payload.node.id, 'Layers Panel')
+1 -1
View File
@@ -213,7 +213,7 @@ function newViewport () {
} else {
newEvent.type = 'Zoom Out'
}
console.log(thisObject.zoomTargetLevel)
thisObject.eventHandler.raiseEvent('Zoom Changed', newEvent)
return true
}
+6 -6
View File
@@ -307,7 +307,7 @@ function newCircularMenuItem () {
if (event !== undefined) {
if (event.type === 'Secondary Action Already Executed') {
setStatus(thisObject.secondaryWorkDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 250, STATUS_SECONDARY_WORK_DONE)
setStatus(thisObject.secondaryWorkDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 100, STATUS_SECONDARY_WORK_DONE)
return
}
}
@@ -316,11 +316,11 @@ function newCircularMenuItem () {
if (thisObject.secondaryAction === undefined) { // This means there are no more possible actions.
if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) {
if (thisObject.workDoneLabel !== undefined) {
setStatus(thisObject.workDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 250, STATUS_PRIMARY_WORK_DONE)
setStatus(thisObject.workDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 100, STATUS_PRIMARY_WORK_DONE)
}
} else {
if (thisObject.workFailedLabel != undefined) {
setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 250, STATUS_PRIMARY_WORK_FAILED)
setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 100, STATUS_PRIMARY_WORK_FAILED)
}
}
} else {
@@ -331,7 +331,7 @@ function newCircularMenuItem () {
}
} else {
if (thisObject.workFailedLabel != undefined) {
setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 250, STATUS_PRIMARY_WORK_FAILED)
setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 100, STATUS_PRIMARY_WORK_FAILED)
}
}
}
@@ -339,11 +339,11 @@ function newCircularMenuItem () {
function onSecondaryCallBack (err) {
if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) {
if (thisObject.secondaryWorkDoneLabel !== undefined) {
setStatus(thisObject.secondaryWorkDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 250, STATUS_SECONDARY_WORK_DONE)
setStatus(thisObject.secondaryWorkDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 100, STATUS_SECONDARY_WORK_DONE)
}
} else {
if (thisObject.secondaryWorkFailedLabel != undefined) {
setStatus(thisObject.secondaryWorkFailedLabel, UI_COLOR.TITANIUM_YELLOW, 250, STATUS_SECONDARY_WORK_FAILED)
setStatus(thisObject.secondaryWorkFailedLabel, UI_COLOR.TITANIUM_YELLOW, 100, STATUS_SECONDARY_WORK_FAILED)
}
}
}
+7 -3
View File
@@ -144,7 +144,7 @@ function newPanelsSpace () {
if (thisObject.panels !== undefined) {
for (let i = 0; i < thisObject.panels.length; i++) {
let panel = thisObject.panels[i]
if (panel.isVisible === false) { continue }
/* setting the speed of the panel */
if (panel.container.speed === undefined) {
panel.container.speed = {
@@ -319,7 +319,9 @@ function newPanelsSpace () {
let panel = thisObject.panels[i]
let owner = canvas.chartSpace.inViewport.get(panel.owner)
if (owner !== undefined) {
panel.draw()
if (panel.isVisible === true) {
panel.draw()
}
}
}
}
@@ -336,7 +338,9 @@ function newPanelsSpace () {
let panel = thisObject.panels[i]
let owner = canvas.chartSpace.inViewport.get(panel.owner)
if (owner !== undefined) {
container = panel.getContainer(point)
if (panel.isVisible === true) {
container = panel.getContainer(point)
}
}
if (container !== undefined) {
return container
@@ -32,6 +32,7 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
let fetchType = "by Time"
let lastId
let firstId
let rateLimit
let exchange
let uiStartDate = new Date(bot.uiStartDate)
@@ -67,6 +68,9 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
if (bot.exchangeNode.code.API[i].firstId !== undefined) {
firstId = bot.exchangeNode.code.API[i].firstId
}
if (bot.exchangeNode.code.API[i].rateLimit !== undefined) {
rateLimit = bot.exchangeNode.code.API[i].rateLimit
}
}
}
}
@@ -87,6 +91,9 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
verbose: false,
options: options
}
if (rateLimit !== undefined) {
exchangeConstructorParams.rateLimit = rateLimit
}
exchange = new exchangeClass(exchangeConstructorParams)
@@ -106,14 +113,16 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
return
}
let abort = false
begin()
async function begin() {
getContextVariables()
if (abort === true) { return }
await getFirstId()
await getTrades()
if (abort === true) { return}
if (global.STOP_TASK_GRACEFULLY === true) {
callBackFunction(global.DEFAULT_OK_RESPONSE);
return
@@ -142,7 +151,7 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
lastFileSaved = new Date(thisReport.file.lastFileSaved.year + "-" + thisReport.file.lastFileSaved.month + "-" + thisReport.file.lastFileSaved.days + " " + thisReport.file.lastFileSaved.hours + ":" + thisReport.file.lastFileSaved.minutes + GMT_SECONDS);
lastId = thisReport.file.lastId
} else { // This means this is the first time this process run.
beginingOfMarket = new Date()
beginingOfMarket = new Date(uiStartDate.valueOf())
}
defineSince()
@@ -158,8 +167,13 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
initialProcessTimestamp = since
beginingOfMarket = new Date(uiStartDate.valueOf())
} else {
since = lastFileSaved.valueOf()
initialProcessTimestamp = lastFileSaved.valueOf()
if (lastFileSaved !== undefined) {
since = lastFileSaved.valueOf()
initialProcessTimestamp = lastFileSaved.valueOf()
} else {
since = uiStartDate.valueOf()
initialProcessTimestamp = uiStartDate.valueOf()
}
}
}
@@ -170,6 +184,7 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
logger.write(MODULE_NAME, "[HINT] start -> getContextVariables -> Dependencies loaded -> keys = " + JSON.stringify(statusDependencies.keys));
}
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
abort = true
}
}
@@ -263,7 +278,7 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> getTrades -> Retrying Later -> err = " + err.stack);
callBackFunction(global.DEFAULT_RETRY_RESPONSE);
abort = true
}
}
@@ -431,6 +446,7 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> saveTrades -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
abort = true
}
}
+1 -1
View File
@@ -38,7 +38,7 @@
'secret': secret,
'timeout': 30000,
'enableRateLimit': true,
verbose: false,
verbose: true,
options: options
}
+1 -1
View File
@@ -475,7 +475,7 @@
/* Validation that we are not going past the head of the market. */
if (bot.multiPeriodProcessDatetime.valueOf() > contextVariables.dateEndOfMarket.valueOf()) {
if (bot.multiPeriodProcessDatetime.valueOf() > contextVariables.dateEndOfMarket.valueOf() + ONE_DAY_IN_MILISECONDS - 1) {
const logText = "Head of the market found @ " + previousDay.getUTCFullYear() + "/" + (previousDay.getUTCMonth() + 1) + "/" + previousDay.getUTCDate() + ".";
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFramesDailyFiles -> advanceTime -> " + logText); }
+27 -15
View File
@@ -1,27 +1,27 @@
{
"_from": "@types/node@^12.0.4",
"_id": "@types/node@12.7.12",
"_from": "@types/node@^13.1.0",
"_id": "@types/node@13.7.0",
"_inBundle": false,
"_integrity": "sha512-KPYGmfD0/b1eXurQ59fXD1GBzhSQfz6/lKBxkaHX9dKTzjXbK68Zt7yGUxUsCS1jeTy/8aL+d9JEr+S54mpkWQ==",
"_integrity": "sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ==",
"_location": "/@types/node",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "@types/node@^12.0.4",
"raw": "@types/node@^13.1.0",
"name": "@types/node",
"escapedName": "@types%2fnode",
"scope": "@types",
"rawSpec": "^12.0.4",
"rawSpec": "^13.1.0",
"saveSpec": null,
"fetchSpec": "^12.0.4"
"fetchSpec": "^13.1.0"
},
"_requiredBy": [
"/telegraf"
],
"_resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.12.tgz",
"_shasum": "7c6c571cc2f3f3ac4a59a5f2bd48f5bdbc8653cc",
"_spec": "@types/node@^12.0.4",
"_resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.0.tgz",
"_shasum": "b417deda18cf8400f278733499ad5547ed1abec4",
"_spec": "@types/node@^13.1.0",
"_where": "C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer\\node_modules\\telegraf",
"bugs": {
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped/issues"
@@ -124,6 +124,10 @@
"name": "Nicolas Voigt",
"url": "https://github.com/octo-sniffle"
},
{
"name": "Nikita Galkin",
"url": "https://github.com/galkin"
},
{
"name": "Parambir Singh",
"url": "https://github.com/parambirs"
@@ -179,6 +183,14 @@
{
"name": "Minh Son Nguyen",
"url": "https://github.com/nguymin4"
},
{
"name": "Junxiao Shi",
"url": "https://github.com/yoursunny"
},
{
"name": "Ilia Baryshnikov",
"url": "https://github.com/qwelias"
}
],
"dependencies": {},
@@ -194,15 +206,15 @@
"directory": "types/node"
},
"scripts": {},
"typeScriptVersion": "2.0",
"types": "index",
"typesPublisherContentHash": "fa0c2ca489bab10e8ffcfbc718f5d7e830d16a4a5052f710937529af9ff3b897",
"typeScriptVersion": "2.8",
"types": "index.d.ts",
"typesPublisherContentHash": "b0cd8dccd6d2eca8bb1de5a05bebf13796984567eb809f63164972122c4ddbaf",
"typesVersions": {
">=3.2.0-0": {
">=3.5.0-0": {
"*": [
"ts3.2/*"
"ts3.5/*"
]
}
},
"version": "12.7.12"
"version": "13.7.0"
}
+94
View File
@@ -0,0 +1,94 @@
"use strict"
const { execSync } = require ('child_process')
const log = require ('ololog').noLocate
const { groupBy } = require ('../ccxt.js')
const { values } = Object
const assert = require ('assert')
function cleanupOldTags () {
const tags = execSync ('git tag').toString ().split ('\n').filter (s => s).map (t => {
const [major, minor, patch] = t.replace ('v', '').split ('.').map (Number)
assert (major < 100)
assert (minor < 100)
return {
key: (major * 100) + minor,
tag: t,
major,
minor,
patch,
}
})
const tagsByMajorMinor = values (groupBy (tags, 'key')).sort ((a, b) => a[0].key - b[0].key)
// Preserve all tags for first 3 minor versions
for (let i = 0; i < 3; i++) {
const tags = tagsByMajorMinor.pop ()
if (tags) {
log.green.bright ('Preserving', tags[0].tag, '...', tags[tags.length - 1].tag)
}
}
// For older versions, leave only "round" numbered versions (1/10th)
let tagsToDelete = []
for (const tags of tagsByMajorMinor) {
for (const { tag, patch } of tags) {
if (patch === 1) {
log.green ('Preserving', tag)
} else {
tagsToDelete.push (tag)
}
}
}
log.bright.red ('Deleting', tagsToDelete.length, 'tags...')
if (!process.argv.includes ('--paper')) {
/* If it happens on a CI server, we don't want it to fail the build because of a super
long execution time (one tag deletion takes ~5 sec...), hence that limit here */
if (process.argv.includes ('--limit')) {
tagsToDelete = tagsToDelete.slice (-500)
}
for (const tag of tagsToDelete) {
log.dim ('Deleting', tag)
execSync (`git tag -d ${tag} && git push origin :refs/tags/${tag}`)
}
}
}
// ============================================================================
// main entry point
if (require.main === module) {
// if called directly like `node module`
cleanupOldTags ()
} else {
// do nothing if required as a module
}
// ============================================================================
module.exports = {
cleanupOldTags,
}
+28 -12
View File
@@ -447,15 +447,19 @@ class Transpiler {
return 'class ' + className + '(' + baseClass + '):'
}
createPythonClassHeader (ccxtImports, bodyAsString) {
createPythonClassHeader (imports, bodyAsString) {
return [
"# -*- coding: utf-8 -*-\n",
"# -*- coding: utf-8 -*-",
"",
"# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:",
"# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code\n",
... ccxtImports,
"# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code",
"",
... imports,
// 'from ' + importFrom + ' import ' + baseClass,
... (bodyAsString.match (/basestring/) ? [
"\n# -----------------------------------------------------------------------------\n",
"",
"# -----------------------------------------------------------------------------",
"",
"try:",
" basestring # Python 3",
"except NameError:",
@@ -464,6 +468,21 @@ class Transpiler {
]
}
createPythonClassImports (baseClass, async = false) {
const baseClasses = {
'Exchange': 'base.exchange',
}
async = (async ? '.async_support' : '')
return [
(baseClass.indexOf ('ccxt.') === 0) ?
('import ccxt' + async + ' as ccxt') :
('from ccxt' + async + '.' + safeString (baseClasses, baseClass, baseClass) + ' import ' + baseClass)
]
}
createPythonClass (className, baseClass, body, methods, async = false) {
const pythonStandardLibraries = {
@@ -471,6 +490,7 @@ class Transpiler {
'hashlib': 'hashlib',
'math': 'math',
'json.loads': 'json',
'sys': 'sys',
}
const baseClasses = {
@@ -479,20 +499,16 @@ class Transpiler {
async = (async ? '.async_support' : '')
const ccxtImports = [
(baseClass.indexOf ('ccxt.') === 0) ?
('import ccxt' + async + ' as ccxt') :
('from ccxt' + async + '.' + safeString (baseClasses, baseClass, baseClass) + ' import ' + baseClass)
]
const imports = this.createPythonClassImports (baseClass, async)
let bodyAsString = body.join ("\n")
let header = this.createPythonClassHeader (ccxtImports, bodyAsString)
let header = this.createPythonClassHeader (imports, bodyAsString)
const libraries = []
for (let library in pythonStandardLibraries) {
const regex = new RegExp ("[^\\']" + library + "[^\\'a-zA-Z]")
const regex = new RegExp ("[^\\'a-zA-Z]" + library + "[^\\'a-zA-Z]")
if (bodyAsString.match (regex))
libraries.push ('import ' + pythonStandardLibraries[library])
}
+1 -2
View File
@@ -35,7 +35,7 @@ const Exchange = require ('./js/base/Exchange')
//-----------------------------------------------------------------------------
// this is updated by vss.js when building
const version = '1.21.82'
const version = '1.22.39'
Exchange.ccxtVersion = version
@@ -45,7 +45,6 @@ const exchanges = {
'_1btcxe': require ('./js/_1btcxe.js'),
'acx': require ('./js/acx.js'),
'adara': require ('./js/adara.js'),
'allcoin': require ('./js/allcoin.js'),
'anxpro': require ('./js/anxpro.js'),
'bcex': require ('./js/bcex.js'),
'bequant': require ('./js/bequant.js'),
+710 -539
View File
File diff suppressed because it is too large. Load diff
+5 -5
View File
@@ -1,6 +1,6 @@
"use strict";
/* ------------------------------------------------------------------------ */
// ----------------------------------------------------------------------------
const functions = require ('./functions')
@@ -411,7 +411,7 @@ module.exports = class Exchange {
}
setSandboxMode (enabled) {
if (!!enabled) {
if (!!enabled) { // eslint-disable-line no-extra-boolean-cast
if ('test' in this.urls) {
if (typeof this.urls['api'] === 'string') {
this.urls['api_backup'] = this.urls['api']
@@ -637,7 +637,7 @@ module.exports = class Exchange {
'limits': this.limits,
'precision': this.precision,
}, this.fees['trading'], market))
this.markets = deepExtend (this.markets, indexBy (values, 'symbol'))
this.markets = indexBy (values, 'symbol')
this.marketsById = indexBy (markets, 'id')
this.markets_by_id = this.marketsById
this.symbols = Object.keys (this.markets).sort ()
@@ -1026,9 +1026,9 @@ module.exports = class Exchange {
return this.markets;
}
filterBySinceLimit (array, since = undefined, limit = undefined) {
filterBySinceLimit (array, since = undefined, limit = undefined, key = 'timestamp') {
if (since !== undefined && since !== null)
array = array.filter (entry => entry.timestamp >= since)
array = array.filter (entry => entry[key] >= since)
if (limit !== undefined && limit !== null)
array = array.slice (0, limit)
return array
+15 -6
View File
@@ -171,8 +171,8 @@ module.exports = class bibox extends Exchange {
'symbol': symbol,
'base': base,
'quote': quote,
'baseId': base,
'quoteId': quote,
'baseId': baseId,
'quoteId': quoteId,
'active': true,
'info': market,
'precision': precision,
@@ -400,7 +400,7 @@ module.exports = class bibox extends Exchange {
for (let i = 0; i < currencies.length; i++) {
const currency = currencies[i];
const id = this.safeString (currency, 'symbol');
const name = this.safeString (currency, 'name');
const name = currency['name']; // contains hieroglyphs causing python ASCII bug
const code = this.safeCurrencyCode (id);
const precision = 8;
const deposit = this.safeValue (currency, 'enable_deposit');
@@ -818,12 +818,21 @@ module.exports = class bibox extends Exchange {
const response = await this.privatePostTransfer (request);
//
// {
// "result":"3Jx6RZ9TNMsAoy9NUzBwZf68QBppDruSKW","cmd":"transfer/transferIn"
// }
//
// {
// "result":"{\"account\":\"PERSONALLY OMITTED\",\"memo\":\"PERSONALLY OMITTED\"}","cmd":"transfer/transferIn"
// }
//
const result = JSON.parse (this.safeString (response, 'result'));
const address = this.safeString (result, 'account');
const tag = this.safeString (result, 'memo');
const result = this.safeString (response, 'result');
let address = result;
let tag = undefined;
if (this.isJsonEncodedObject (result)) {
const parsed = JSON.parse (result);
address = this.safeString (parsed, 'account');
tag = this.safeString (parsed, 'memo');
}
return {
'currency': code,
'address': address,
+51 -14
View File
@@ -85,6 +85,7 @@ module.exports = class binance extends Exchange {
// the API structure below will need 3-layer apidefs
'sapi': {
'get': [
'accountSnapshot',
// these endpoints require this.apiKey
'margin/asset',
'margin/pair',
@@ -108,13 +109,30 @@ module.exports = class binance extends Exchange {
'futures/transfer',
// https://binance-docs.github.io/apidocs/spot/en/#withdraw-sapi
'capital/config/getall', // get networks for withdrawing USDT ERC20 vs USDT Omni
'capital/deposit/address',
'capital/deposit/hisrec',
'capital/deposit/subAddress',
'capital/deposit/subHisrec',
'capital/withdraw/history',
'sub-account/futures/account',
'sub-account/futures/accountSummary',
'sub-account/futures/positionRisk',
'sub-account/margin/account',
'sub-account/margin/accountSummary',
'sub-account/status',
],
'post': [
'asset/dust',
'account/disableFastWithdrawSwitch',
'account/enableFastWithdrawSwitch',
'capital/withdraw/apply',
'margin/transfer',
'margin/loan',
'margin/repay',
'margin/order',
'sub-account/margin/enable',
'sub-account/margin/enable',
'sub-account/futures/enable',
'userDataStream',
'futures/transfer',
],
@@ -185,6 +203,7 @@ module.exports = class binance extends Exchange {
],
'delete': [
'order',
'allOpenOrders',
],
},
'v3': {
@@ -849,6 +868,8 @@ module.exports = class binance extends Exchange {
if (this.options['fetchTradesMethod'] === 'publicGetAggTrades') {
if (since !== undefined) {
request['startTime'] = since;
// https://github.com/ccxt/ccxt/issues/6400
// https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#compressedaggregate-trades-list
request['endTime'] = this.sum (since, 3600000);
}
}
@@ -1039,7 +1060,7 @@ module.exports = class binance extends Exchange {
'type': uppercaseType,
'side': side.toUpperCase (),
};
if (type === 'market') {
if (uppercaseType === 'MARKET') {
const quoteOrderQty = this.safeFloat (params, 'quoteOrderQty');
if (quoteOrderQty !== undefined) {
request['quoteOrderQty'] = this.costToPrecision (symbol, quoteOrderQty);
@@ -1707,23 +1728,39 @@ module.exports = class binance extends Exchange {
}
const userDataStream = ((path === 'userDataStream') || (path === 'listenKey'));
if (path === 'historicalTrades') {
headers = {
'X-MBX-APIKEY': this.apiKey,
};
if (this.apiKey) {
headers = {
'X-MBX-APIKEY': this.apiKey,
};
} else {
throw new AuthenticationError (this.id + ' historicalTrades endpoint requires `apiKey` credential');
}
} else if (userDataStream) {
// v1 special case for userDataStream
body = this.urlencode (params);
headers = {
'X-MBX-APIKEY': this.apiKey,
'Content-Type': 'application/x-www-form-urlencoded',
};
if (this.apiKey) {
// v1 special case for userDataStream
body = this.urlencode (params);
headers = {
'X-MBX-APIKEY': this.apiKey,
'Content-Type': 'application/x-www-form-urlencoded',
};
} else {
throw new AuthenticationError (this.id + ' userDataStream endpoint requires `apiKey` credential');
}
}
if ((api === 'private') || (api === 'sapi') || (api === 'wapi' && path !== 'systemStatus') || (api === 'fapiPrivate')) {
this.checkRequiredCredentials ();
let query = this.urlencode (this.extend ({
'timestamp': this.nonce (),
'recvWindow': this.options['recvWindow'],
}, params));
let query = undefined;
if ((api === 'sapi') && (path === 'asset/dust')) {
query = this.urlencodeWithArrayRepeat (this.extend ({
'timestamp': this.nonce (),
'recvWindow': this.options['recvWindow'],
}, params));
} else {
query = this.urlencode (this.extend ({
'timestamp': this.nonce (),
'recvWindow': this.options['recvWindow'],
}, params));
}
const signature = this.hmac (this.encode (query), this.encode (this.secret));
query += '&' + 'signature=' + signature;
headers = {
+9 -1
View File
@@ -543,11 +543,19 @@ module.exports = class bitfinex extends Exchange {
} else {
key = 'base';
}
const code = market[key];
const currency = this.safeValue (this.currencies, code);
if (currency !== undefined) {
const precision = this.safeInteger (currency, 'precision');
if (precision !== undefined) {
cost = parseFloat (this.currencyToPrecision (code, cost));
}
}
return {
'type': takerOrMaker,
'currency': market[key],
'rate': rate,
'cost': parseFloat (this.currencyToPrecision (market[key], cost)),
'cost': cost,
};
}
+1
View File
@@ -33,6 +33,7 @@ module.exports = class bitfinex2 extends bitfinex {
'fetchTickers': true,
'fetchTradingFee': false,
'fetchTradingFees': false,
'fetchTransactions': false,
'withdraw': true,
},
'timeframes': {
+2 -2
View File
@@ -31,7 +31,7 @@ module.exports = class bitforex extends Exchange {
},
'timeframes': {
'1m': '1min',
'5m': 'M5',
'5m': '5min',
'15m': '15min',
'30m': '30min',
'1h': '1hour',
@@ -46,7 +46,7 @@ module.exports = class bitforex extends Exchange {
'logo': 'https://user-images.githubusercontent.com/1294454/44310033-69e9e600-a3d8-11e8-873d-54d74d1bc4e4.jpg',
'api': 'https://api.bitforex.com',
'www': 'https://www.bitforex.com',
'doc': 'https://github.com/bitforexapi/API_Docs/wiki',
'doc': 'https://github.com/githubdev2020/API_Doc_en/wiki',
'fees': 'https://help.bitforex.com/en_us/?cat=13',
'referral': 'https://www.bitforex.com/en/invitationRegister?inviterId=1867438',
},
+13 -2
View File
@@ -165,8 +165,19 @@ module.exports = class btcalpha extends Exchange {
request['limit_sell'] = limit;
request['limit_buy'] = limit;
}
const reponse = await this.publicGetOrderbookPairName (this.extend (request, params));
return this.parseOrderBook (reponse, undefined, 'buy', 'sell', 'price', 'amount');
const response = await this.publicGetOrderbookPairName (this.extend (request, params));
return this.parseOrderBook (response, undefined, 'buy', 'sell', 'price', 'amount');
}
parseBidsAsks (bidasks, priceKey = 0, amountKey = 1) {
const result = [];
for (let i = 0; i < bidasks.length; i++) {
const bidask = bidasks[i];
if (bidask) {
result.push (this.parseBidAsk (bidask, priceKey, amountKey));
}
}
return result;
}
parseTrade (trade, market = undefined) {
+24 -2
View File
@@ -28,7 +28,7 @@ module.exports = class bw extends Exchange {
'editOrder': false,
'fetchBalance': true,
'fetchBidsAsks': false,
'fetchClosedOrders': false,
'fetchClosedOrders': true,
'fetchCurrencies': true,
'fetchDepositAddress': true,
'fetchDeposits': true,
@@ -119,6 +119,7 @@ module.exports = class bw extends Exchange {
'exchange/entrust/controller/website/EntrustController/getUserEntrustList',
'exchange/fund/controller/website/fundwebsitecontroller/getwithdrawaddress',
'exchange/fund/controller/website/fundwebsitecontroller/getpayoutcoinrecord',
'exchange/entrust/controller/website/EntrustController/getUserEntrustList',
// the docs say that the following URLs are HTTP POST
// in the docs header and HTTP GET in the docs body
// the docs contradict themselves, a typo most likely
@@ -861,6 +862,27 @@ module.exports = class bw extends Exchange {
return this.parseOrders (orders, market, since, limit);
}
async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
if (symbol === undefined) {
throw new ArgumentsRequired (this.id + ' fetchClosedOrders() requires a symbol argument');
}
await this.loadMarkets ();
const market = this.market (symbol);
const request = {
'marketId': market['id'],
};
if (limit !== undefined) {
request['pageSize'] = limit; // default limit is 20
}
if (since !== undefined) {
request['startDateTime'] = since;
}
const response = await this.privateGetExchangeEntrustControllerWebsiteEntrustControllerGetUserEntrustList (this.extend (request, params));
const data = this.safeValue (response, 'datas', {});
const orders = this.safeValue (data, 'entrustList', []);
return this.parseOrders (orders, market, since, limit);
}
async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
if (symbol === undefined) {
throw new ArgumentsRequired (this.id + ' fetchOpenOrders() requires a symbol argument');
@@ -932,7 +954,7 @@ module.exports = class bw extends Exchange {
const keys = Object.keys (sortedParams);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
content += key + sortedParams[key];
content += key + sortedParams[key].toString ();
}
} else {
content = body;
+1 -1
View File
@@ -14,7 +14,7 @@ module.exports = class coinbaseprime extends coinbasepro {
'urls': {
'test': {
'public': 'https://api-public.sandbox.prime.coinbase.com',
'private:': 'https://api-public.sandbox.prime.coinbase.com',
'private': 'https://api-public.sandbox.prime.coinbase.com',
},
'logo': 'https://user-images.githubusercontent.com/1294454/44539184-29f26e00-a70c-11e8-868f-e907fc236a7c.jpg',
'api': {
+90 -16
View File
@@ -3,7 +3,7 @@
// ----------------------------------------------------------------------------
const Exchange = require ('./base/Exchange');
const { InsufficientFunds, ArgumentsRequired, ExchangeError, InvalidOrder, InvalidAddress, AuthenticationError, NotSupported, OrderNotFound } = require ('./base/errors');
const { InsufficientFunds, ArgumentsRequired, ExchangeError, InvalidOrder, InvalidAddress, AuthenticationError, NotSupported, OrderNotFound, OnMaintenance, RateLimitExceeded } = require ('./base/errors');
// ----------------------------------------------------------------------------
@@ -152,12 +152,14 @@ module.exports = class coinbasepro extends Exchange {
'invalid signature': AuthenticationError,
'Invalid Passphrase': AuthenticationError,
'Invalid order id': InvalidOrder,
'Private rate limit exceeded': RateLimitExceeded,
},
'broad': {
'Order already done': OrderNotFound,
'order not found': OrderNotFound,
'price too small': InvalidOrder,
'price too precise': InvalidOrder,
'under maintenance': OnMaintenance,
},
},
});
@@ -295,29 +297,46 @@ module.exports = class coinbasepro extends Exchange {
return orderbook;
}
async fetchTicker (symbol, params = {}) {
await this.loadMarkets ();
const market = this.market (symbol);
const request = {
'id': market['id'],
};
const ticker = await this.publicGetProductsIdTicker (this.extend (request, params));
parseTicker (ticker, market = undefined) {
//
// publicGetProductsIdTicker
//
// {
// "trade_id":843439,
// "price":"0.997999",
// "size":"80.29769",
// "time":"2020-01-28T02:13:33.012523Z",
// "bid":"0.997094",
// "ask":"0.998",
// "volume":"1903188.03750000"
// }
//
// publicGetProductsIdStats
//
// {
// "open": "34.19000000",
// "high": "95.70000000",
// "low": "7.06000000",
// "volume": "2.41000000"
// }
//
const timestamp = this.parse8601 (this.safeValue (ticker, 'time'));
const bid = this.safeFloat (ticker, 'bid');
const ask = this.safeFloat (ticker, 'ask');
const last = this.safeFloat (ticker, 'price');
const symbol = (market === undefined) ? undefined : market['symbol'];
return {
'symbol': symbol,
'timestamp': timestamp,
'datetime': this.iso8601 (timestamp),
'high': undefined,
'low': undefined,
'high': this.safeFloat (ticker, 'high'),
'low': this.safeFloat (ticker, 'low'),
'bid': bid,
'bidVolume': undefined,
'ask': ask,
'askVolume': undefined,
'vwap': undefined,
'open': undefined,
'open': this.safeFloat (ticker, 'open'),
'close': last,
'last': last,
'previousClose': undefined,
@@ -330,14 +349,69 @@ module.exports = class coinbasepro extends Exchange {
};
}
async fetchTicker (symbol, params = {}) {
await this.loadMarkets ();
const market = this.market (symbol);
const request = {
'id': market['id'],
};
// publicGetProductsIdTicker or publicGetProductsIdStats
const method = this.safeString (this.options, 'fetchTickerMethod', 'publicGetProductsIdTicker');
const response = await this[method] (this.extend (request, params));
//
// publicGetProductsIdTicker
//
// {
// "trade_id":843439,
// "price":"0.997999",
// "size":"80.29769",
// "time":"2020-01-28T02:13:33.012523Z",
// "bid":"0.997094",
// "ask":"0.998",
// "volume":"1903188.03750000"
// }
//
// publicGetProductsIdStats
//
// {
// "open": "34.19000000",
// "high": "95.70000000",
// "low": "7.06000000",
// "volume": "2.41000000"
// }
//
return this.parseTicker (response, market);
}
parseTrade (trade, market = undefined) {
//
// {
// type: 'match',
// trade_id: 82047307,
// maker_order_id: '0f358725-2134-435e-be11-753912a326e0',
// taker_order_id: '252b7002-87a3-425c-ac73-f5b9e23f3caf',
// side: 'sell',
// size: '0.00513192',
// price: '9314.78',
// product_id: 'BTC-USD',
// sequence: 12038915443,
// time: '2020-01-31T20:03:41.158814Z'
// }
//
const timestamp = this.parse8601 (this.safeString2 (trade, 'time', 'created_at'));
let symbol = undefined;
if (market === undefined) {
const marketId = this.safeString (trade, 'product_id');
market = this.safeValue (this.markets_by_id, marketId);
const marketId = this.safeString (trade, 'product_id');
if (marketId !== undefined) {
if (marketId in this.markets_by_id) {
market = this.markets_by_id[marketId];
} else {
const [ baseId, quoteId ] = marketId.split ('-');
const base = this.safeCurrencyCode (baseId);
const quote = this.safeCurrencyCode (quoteId);
symbol = base + '/' + quote;
}
}
if (market) {
if ((symbol === undefined) && (market !== undefined)) {
symbol = market['symbol'];
}
let feeRate = undefined;
@@ -861,7 +935,7 @@ module.exports = class coinbasepro extends Exchange {
handleErrors (code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
if ((code === 400) || (code === 404)) {
if (body[0] === '{') {
const message = response['message'];
const message = this.safeString (response, 'message');
const feedback = this.id + ' ' + message;
this.throwExactlyMatchedException (this.exceptions['exact'], message, feedback);
this.throwBroadlyMatchedException (this.exceptions['broad'], message, feedback);
-3
View File
@@ -315,9 +315,6 @@ module.exports = class crex24 extends Exchange {
// }
// ]
//
// const log = require ('ololog').unlimited.green;
// log (response);
// process.exit ();
const result = { 'info': response };
for (let i = 0; i < response.length; i++) {
const balance = response[i];
+4 -1
View File
@@ -444,7 +444,7 @@ module.exports = class dsx extends Exchange {
return this.parseOrderBook (orderbook);
}
async fetchOrderBooks (symbols = undefined, params = {}) {
async fetchOrderBooks (symbols = undefined, limit = undefined, params = {}) {
await this.loadMarkets ();
let ids = undefined;
if (symbols === undefined) {
@@ -461,6 +461,9 @@ module.exports = class dsx extends Exchange {
const request = {
'pair': ids,
};
if (limit !== undefined) {
request['limit'] = limit; // default = 150, max = 2000
}
const response = await this.publicGetDepthPair (this.extend (request, params));
const result = {};
ids = Object.keys (response);
+23 -14
View File
@@ -3,7 +3,7 @@
// ---------------------------------------------------------------------------
const Exchange = require ('./base/Exchange');
const { ArgumentsRequired, ExchangeError, OrderNotFound, AuthenticationError, InsufficientFunds, InvalidOrder, InvalidNonce, NotSupported, OnMaintenance } = require ('./base/errors');
const { ArgumentsRequired, ExchangeError, OrderNotFound, AuthenticationError, InsufficientFunds, InvalidOrder, InvalidNonce, NotSupported, OnMaintenance, RateLimitExceeded } = require ('./base/errors');
// ---------------------------------------------------------------------------
@@ -384,17 +384,22 @@ module.exports = class exmo extends Exchange {
},
},
'exceptions': {
'40005': AuthenticationError, // Authorization error, incorrect signature
'40009': InvalidNonce, //
'40015': ExchangeError, // API function do not exist
'40016': OnMaintenance, // {"result":false,"error":"Error 40016: Maintenance work in progress"}
'40017': AuthenticationError, // Wrong API Key
'50052': InsufficientFunds,
'50054': InsufficientFunds,
'50304': OrderNotFound, // "Order was not found '123456789'" (fetching order trades for an order that does not have trades yet)
'50173': OrderNotFound, // "Order with id X was not found." (cancelling non-existent, closed and cancelled order)
'50319': InvalidOrder, // Price by order is less than permissible minimum for this pair
'50321': InvalidOrder, // Price by order is more than permissible maximum for this pair
'exact': {
'40005': AuthenticationError, // Authorization error, incorrect signature
'40009': InvalidNonce, //
'40015': ExchangeError, // API function do not exist
'40016': OnMaintenance, // {"result":false,"error":"Error 40016: Maintenance work in progress"}
'40017': AuthenticationError, // Wrong API Key
'50052': InsufficientFunds,
'50054': InsufficientFunds,
'50304': OrderNotFound, // "Order was not found '123456789'" (fetching order trades for an order that does not have trades yet)
'50173': OrderNotFound, // "Order with id X was not found." (cancelling non-existent, closed and cancelled order)
'50319': InvalidOrder, // Price by order is less than permissible minimum for this pair
'50321': InvalidOrder, // Price by order is more than permissible maximum for this pair
},
'broad': {
'API rate limit exceeded': RateLimitExceeded, // {"result":false,"error":"API rate limit exceeded for 99.33.55.224. Retry after 60 sec.","history":[],"begin":1579392000,"end":1579478400}
},
},
});
}
@@ -633,7 +638,7 @@ module.exports = class exmo extends Exchange {
return this.parseOrderBook (result, undefined, 'bid', 'ask');
}
async fetchOrderBooks (symbols = undefined, params = {}) {
async fetchOrderBooks (symbols = undefined, limit = undefined, params = {}) {
await this.loadMarkets ();
let ids = undefined;
if (symbols === undefined) {
@@ -650,6 +655,9 @@ module.exports = class exmo extends Exchange {
const request = {
'pair': ids,
};
if (limit !== undefined) {
request['limit'] = limit;
}
const response = await this.publicGetOrderBook (this.extend (request, params));
const result = {};
const marketIds = Object.keys (response);
@@ -1396,7 +1404,8 @@ module.exports = class exmo extends Exchange {
code = (numSubParts > 1) ? errorSubParts[1] : errorSubParts[0];
}
const feedback = this.id + ' ' + body;
this.throwExactlyMatchedException (this.exceptions, code, feedback);
this.throwExactlyMatchedException (this.exceptions['exact'], code, feedback);
this.throwBroadlyMatchedException (this.exceptions['broad'], message, feedback);
throw new ExchangeError (feedback);
}
}
+17 -14
View File
@@ -34,18 +34,18 @@ module.exports = class gateio extends Exchange {
'fetchMyTrades': true,
},
'timeframes': {
'1m': '60',
'5m': '300',
'10m': '600',
'15m': '900',
'30m': '1800',
'1h': '3600',
'2h': '7200',
'4h': '14400',
'6h': '21600',
'12h': '43200',
'1d': '86400',
'1w': '604800',
'1m': 60,
'5m': 300,
'10m': 600,
'15m': 900,
'30m': 1800,
'1h': 3600,
'2h': 7200,
'4h': 14400,
'6h': 21600,
'12h': 43200,
'1d': 86400,
'1w': 604800,
},
'urls': {
'logo': 'https://user-images.githubusercontent.com/1294454/31784029-0313c702-b509-11e7-9ccc-bc0da6a0e435.jpg',
@@ -165,7 +165,7 @@ module.exports = class gateio extends Exchange {
for (let i = 0; i < markets.length; i++) {
const market = markets[i];
const keys = Object.keys (market);
const id = keys[0];
const id = this.safeString (keys, 0);
const details = market[id];
// all of their symbols are separated with an underscore
// but not boe_eth_eth (BOE_ETH/ETH) which has two underscores
@@ -731,7 +731,10 @@ module.exports = class gateio extends Exchange {
const id = this.safeString (transaction, 'id');
const txid = this.safeString (transaction, 'txid');
const amount = this.safeFloat (transaction, 'amount');
const address = this.safeString (transaction, 'address');
let address = this.safeString (transaction, 'address');
if (address === 'false') {
address = undefined;
}
const timestamp = this.safeTimestamp (transaction, 'timestamp');
const status = this.parseTransactionStatus (this.safeString (transaction, 'status'));
const type = this.parseTransactionType (id[0]);
+17
View File
@@ -87,14 +87,22 @@ module.exports = class huobipro extends Exchange {
],
},
'private': {
// todo add v2 endpoints
// 'GET /v2/account/withdraw/quota
// 'GET /v2/reference/currencies
// 'GET /v2/account/deposit/address
'get': [
'account/accounts', // 查询当前用户的所有账户(即account-id)
'account/accounts/{id}/balance', // 查询指定账户的余额
'account/accounts/{sub-uid}',
'account/history',
'cross-margin/loan-info',
'fee/fee-rate/get',
'order/openOrders',
'order/orders',
'order/orders/{id}', // 查询某个订单详情
'order/orders/{id}/matchresults', // 查询某个订单的成交明细
'order/orders/getClientOrder',
'order/history', // 查询当前委托、历史委托
'order/matchresults', // 查询当前成交、历史成交
'dw/withdraw-virtual/addresses', // 查询虚拟币提现地址
@@ -104,9 +112,17 @@ module.exports = class huobipro extends Exchange {
'points/actions',
'points/orders',
'subuser/aggregate-balance',
'stable-coin/exchange_rate',
'stable-coin/quote',
],
// todo add v2 endpoints
// POST /v2/sub-user/management
'post': [
'futures/transfer',
'order/batch-orders',
'order/orders/place', // 创建并执行一个新订单 (一步下单, 推荐使用)
'order/orders/submitCancelClientOrder',
'order/orders/batchCancelOpenOrders',
'order/orders', // 创建一个新的订单请求 (仅创建订单,不执行下单)
'order/orders/{id}/place', // 执行一个订单 (仅执行已创建的订单)
'order/orders/{id}/submitcancel', // 申请撤销一个订单请求
@@ -120,6 +136,7 @@ module.exports = class huobipro extends Exchange {
'dw/transfer-out/margin', // 借贷账户划出至现货账户
'margin/orders', // 申请借贷
'margin/orders/{id}/repay', // 归还借贷
'stable-coin/exchange',
'subuser/transfer',
],
},
+12 -4
View File
@@ -71,11 +71,13 @@ module.exports = class indodax extends Exchange {
'ATOM/IDR': { 'id': 'atom_idr', 'symbol': 'ATOM/IDR', 'base': 'ATOM', 'quote': 'IDR', 'baseId': 'atom', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': undefined, 'max': undefined }}},
'BAT/IDR': { 'id': 'bat_idr', 'symbol': 'BAT/IDR', 'base': 'BAT', 'quote': 'IDR', 'baseId': 'bat', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': undefined, 'max': undefined }}},
'BCD/IDR': { 'id': 'bcd_idr', 'symbol': 'BCD/IDR', 'base': 'BCD', 'quote': 'IDR', 'baseId': 'bcd', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': undefined, 'max': undefined }}},
'BCH/IDR': { 'id': 'bch_idr', 'symbol': 'BCH/IDR', 'base': 'BCH', 'quote': 'IDR', 'baseId': 'bch', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.001, 'max': undefined }}},
'BSV/IDR': { 'id': 'bsv_idr', 'symbol': 'BSV/IDR', 'base': 'BSV', 'quote': 'IDR', 'baseId': 'bsv', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.001, 'max': undefined }}},
'BCH/IDR': { 'id': 'bchabc_idr', 'symbol': 'BCH/IDR', 'base': 'BCH', 'quote': 'IDR', 'baseId': 'bchabc', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.001, 'max': undefined }}},
'BSV/IDR': { 'id': 'bchsv_idr', 'symbol': 'BSV/IDR', 'base': 'BSV', 'quote': 'IDR', 'baseId': 'bchsv', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.001, 'max': undefined }}},
'BNB/IDR': { 'id': 'bnb_idr', 'symbol': 'BNB/IDR', 'base': 'BNB', 'quote': 'IDR', 'baseId': 'bnb', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.001, 'max': undefined }}},
'BTG/IDR': { 'id': 'btg_idr', 'symbol': 'BTG/IDR', 'base': 'BTG', 'quote': 'IDR', 'baseId': 'btg', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.01, 'max': undefined }}},
'BTS/IDR': { 'id': 'bts_idr', 'symbol': 'BTS/IDR', 'base': 'BTS', 'quote': 'IDR', 'baseId': 'bts', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.01, 'max': undefined }}},
'BTT/IDR': { 'id': 'btt_idr', 'symbol': 'BTT/IDR', 'base': 'BTT', 'quote': 'IDR', 'baseId': 'btt', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 1000, 'max': undefined }}},
'COAL/IDR': { 'id': 'coal_idr', 'symbol': 'COAL/IDR', 'base': 'COAL', 'quote': 'IDR', 'baseId': 'coal', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 50, 'max': undefined }}},
'CRO/IDR': { 'id': 'cro_idr', 'symbol': 'CRO/IDR', 'base': 'CRO', 'quote': 'IDR', 'baseId': 'cro', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.01, 'max': undefined }}},
'DASH/IDR': { 'id': 'drk_idr', 'symbol': 'DASH/IDR', 'base': 'DASH', 'quote': 'IDR', 'baseId': 'drk', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.01, 'max': undefined }}},
'DAX/IDR': { 'id': 'dax_idr', 'symbol': 'DAX/IDR', 'base': 'DAX', 'quote': 'IDR', 'baseId': 'dax', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.01, 'max': undefined }}},
@@ -85,15 +87,18 @@ module.exports = class indodax extends Exchange {
'ETC/IDR': { 'id': 'etc_idr', 'symbol': 'ETC/IDR', 'base': 'ETC', 'quote': 'IDR', 'baseId': 'etc', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.1, 'max': undefined }}},
'GARD/IDR': { 'id': 'gard_idr', 'symbol': 'GARD/IDR', 'base': 'GARD', 'quote': 'IDR', 'baseId': 'gard', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.1, 'max': undefined }}},
'GSC/IDR': { 'id': 'gsc_idr', 'symbol': 'GSC/IDR', 'base': 'GSC', 'quote': 'IDR', 'baseId': 'gsc', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.1, 'max': undefined }}},
'GXC/IDR': { 'id': 'gxc_idr', 'symbol': 'GXC/IDR', 'base': 'GXC', 'quote': 'IDR', 'baseId': 'gxc', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.1, 'max': undefined }}},
'GXC/IDR': { 'id': 'gxs_idr', 'symbol': 'GXC/IDR', 'base': 'GXC', 'quote': 'IDR', 'baseId': 'gxs', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.1, 'max': undefined }}},
'HPB/IDR': { 'id': 'hpb_idr', 'symbol': 'HPB/IDR', 'base': 'HPB', 'quote': 'IDR', 'baseId': 'hpb', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 5, 'max': undefined }}},
'IGNIS/IDR': { 'id': 'ignis_idr', 'symbol': 'IGNIS/IDR', 'base': 'IGNIS', 'quote': 'IDR', 'baseId': 'ignis', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 1, 'max': undefined }}},
'INX/IDR': { 'id': 'inx_idr', 'symbol': 'INX/IDR', 'base': 'INX', 'quote': 'IDR', 'baseId': 'inx', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 1, 'max': undefined }}},
'IOTA/IDR': { 'id': 'iota_idr', 'symbol': 'IOTA/IDR', 'base': 'IOTA', 'quote': 'IDR', 'baseId': 'iota', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 5, 'max': undefined }}},
'LINK/IDR': { 'id': 'link_idr', 'symbol': 'LINK/IDR', 'base': 'LINK', 'quote': 'IDR', 'baseId': 'link', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 1, 'max': undefined }}},
'LTC/IDR': { 'id': 'ltc_idr', 'symbol': 'LTC/IDR', 'base': 'LTC', 'quote': 'IDR', 'baseId': 'ltc', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.01, 'max': undefined }}},
'MBL/IDR': { 'id': 'mbl_idr', 'symbol': 'MBL/IDR', 'base': 'MBL', 'quote': 'IDR', 'baseId': 'mbl', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.01, 'max': undefined }}},
'NEO/IDR': { 'id': 'neo_idr', 'symbol': 'NEO/IDR', 'base': 'NEO', 'quote': 'IDR', 'baseId': 'neo', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.01, 'max': undefined }}},
'NPXS/IDR': { 'id': 'npxs_idr', 'symbol': 'NPXS/IDR', 'base': 'NPXS', 'quote': 'IDR', 'baseId': 'npxs', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 1, 'max': undefined }}},
'NXT/IDR': { 'id': 'nxt_idr', 'symbol': 'NXT/IDR', 'base': 'NXT', 'quote': 'IDR', 'baseId': 'nxt', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 5, 'max': undefined }}},
'OKB/IDR': { 'id': 'okb_idr', 'symbol': 'OKB/IDR', 'base': 'OKB', 'quote': 'IDR', 'baseId': 'okb', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.5, 'max': undefined }}},
'ONT/IDR': { 'id': 'ont_idr', 'symbol': 'ONT/IDR', 'base': 'ONT', 'quote': 'IDR', 'baseId': 'ont', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 5, 'max': undefined }}},
'PXG/IDR': { 'id': 'pxg_idr', 'symbol': 'PXG/IDR', 'base': 'PXG', 'quote': 'IDR', 'baseId': 'pxg', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 5, 'max': undefined }}},
'QTUM/IDR': { 'id': 'qtum_idr', 'symbol': 'QTUM/IDR', 'base': 'QTUM', 'quote': 'IDR', 'baseId': 'qtum', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 5, 'max': undefined }}},
@@ -105,13 +110,16 @@ module.exports = class indodax extends Exchange {
'USDC/IDR': { 'id': 'usdc_idr', 'symbol': 'USDC/IDR', 'base': 'USDC', 'quote': 'IDR', 'baseId': 'usdc', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': undefined, 'max': undefined }}},
'USDT/IDR': { 'id': 'usdt_idr', 'symbol': 'USDT/IDR', 'base': 'USDT', 'quote': 'IDR', 'baseId': 'usdt', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': undefined, 'max': undefined }}},
'VEX/IDR': { 'id': 'vex_idr', 'symbol': 'VEX/IDR', 'base': 'VEX', 'quote': 'IDR', 'baseId': 'vex', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': undefined, 'max': undefined }}},
'VIDY/IDR': { 'id': 'vidy_idr', 'symbol': 'VIDY/IDR', 'base': 'VIDY', 'quote': 'IDR', 'baseId': 'vidy', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 100, 'max': undefined }}},
'WAVES/IDR': { 'id': 'waves_idr', 'symbol': 'WAVES/IDR', 'base': 'WAVES', 'quote': 'IDR', 'baseId': 'waves', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.1, 'max': undefined }}},
'XEM/IDR': { 'id': 'nem_idr', 'symbol': 'XEM/IDR', 'base': 'XEM', 'quote': 'IDR', 'baseId': 'nem', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 1, 'max': undefined }}},
'XLM/IDR': { 'id': 'str_idr', 'symbol': 'XLM/IDR', 'base': 'XLM', 'quote': 'IDR', 'baseId': 'str', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 20, 'max': undefined }}},
'XDCE/IDR': { 'id': 'xdce_idr', 'symbol': 'XDCE/IDR', 'base': 'XDCE', 'quote': 'IDR', 'baseId': 'xdce', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 10, 'max': undefined }}},
'XMR/IDR': { 'id': 'xmr_idr', 'symbol': 'XMR/IDR', 'base': 'XMR', 'quote': 'IDR', 'baseId': 'xmr', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.01, 'max': undefined }}},
'XRP/IDR': { 'id': 'xrp_idr', 'symbol': 'XRP/IDR', 'base': 'XRP', 'quote': 'IDR', 'baseId': 'xrp', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 10, 'max': undefined }}},
'XZC/IDR': { 'id': 'xzc_idr', 'symbol': 'XZC/IDR', 'base': 'XZC', 'quote': 'IDR', 'baseId': 'xzc', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.1, 'max': undefined }}},
'VSYS/IDR': { 'id': 'vsys_idr', 'symbol': 'VSYS/IDR', 'base': 'VSYS', 'quote': 'IDR', 'baseId': 'vsys', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.1, 'max': undefined }}},
'ZEC/IDR': { 'id': 'zec_idr', 'symbol': 'ZEC/IDR', 'base': 'ZEC', 'quote': 'IDR', 'baseId': 'zec', 'quoteId': 'idr', 'precision': { 'amount': 8, 'price': 0 }, 'limits': { 'amount': { 'min': 0.01, 'max': undefined }}},
// BTC markets
'BTS/BTC': { 'id': 'bts_btc', 'symbol': 'BTS/BTC', 'base': 'BTS', 'quote': 'BTC', 'baseId': 'bts', 'quoteId': 'btc', 'precision': { 'amount': 8, 'price': 8 }, 'limits': { 'amount': { 'min': 0.01, 'max': undefined }}},
'DASH/BTC': { 'id': 'drk_btc', 'symbol': 'DASH/BTC', 'base': 'DASH', 'quote': 'BTC', 'baseId': 'drk', 'quoteId': 'btc', 'precision': { 'amount': 8, 'price': 6 }, 'limits': { 'amount': { 'min': 0.01, 'max': undefined }}},
@@ -279,7 +287,7 @@ module.exports = class indodax extends Exchange {
let status = this.safeString (order, 'status', 'open');
if (status === 'filled') {
status = 'closed';
} else if (status === 'calcelled') {
} else if (status === 'cancelled') {
status = 'canceled';
}
let symbol = undefined;
+9 -9
View File
@@ -38,15 +38,15 @@ module.exports = class kraken extends Exchange {
},
'marketsByAltname': {},
'timeframes': {
'1m': '1',
'5m': '5',
'15m': '15',
'30m': '30',
'1h': '60',
'4h': '240',
'1d': '1440',
'1w': '10080',
'2w': '21600',
'1m': 1,
'5m': 5,
'15m': 15,
'30m': 30,
'1h': 60,
'4h': 240,
'1d': 1440,
'1w': 10080,
'2w': 21600,
},
'urls': {
'logo': 'https://user-images.githubusercontent.com/1294454/27766599-22709304-5ede-11e7-9de1-9f33732e1509.jpg',
+54 -20
View File
@@ -15,7 +15,7 @@ module.exports = class kucoin extends Exchange {
'countries': [ 'SC' ],
'rateLimit': 334,
'version': 'v2',
'certified': true,
'certified': false,
'comment': 'Platform 2.0',
'has': {
'fetchTime': true,
@@ -368,24 +368,47 @@ module.exports = class kucoin extends Exchange {
parseTicker (ticker, market = undefined) {
//
// {
// 'buy': '0.00001168',
// 'changePrice': '-0.00000018',
// 'changeRate': '-0.0151',
// 'datetime': 1550661146316,
// 'high': '0.0000123',
// 'last': '0.00001169',
// 'low': '0.00001159',
// 'sell': '0.00001182',
// 'symbol': 'LOOM-BTC',
// 'vol': '44399.5669'
// symbol: "ETH-BTC",
// high: "0.019518",
// vol: "7997.82836194",
// last: "0.019329",
// low: "0.019",
// buy: "0.019329",
// sell: "0.01933",
// changePrice: "-0.000139",
// time: 1580553706304,
// averagePrice: "0.01926386",
// changeRate: "-0.0071",
// volValue: "154.40791568183474"
// }
//
// {
// "trading": true,
// "symbol": "KCS-BTC",
// "buy": 0.00011,
// "sell": 0.00012,
// "sort": 100,
// "volValue": 3.13851792584, //total
// "baseCurrency": "KCS",
// "market": "BTC",
// "quoteCurrency": "BTC",
// "symbolCode": "KCS-BTC",
// "datetime": 1548388122031,
// "high": 0.00013,
// "vol": 27514.34842,
// "low": 0.0001,
// "changePrice": -1.0e-5,
// "changeRate": -0.0769,
// "lastTradedPrice": 0.00012,
// "board": 0,
// "mark": 0
// }
//
let percentage = this.safeFloat (ticker, 'changeRate');
if (percentage !== undefined) {
percentage = percentage * 100;
}
const last = this.safeFloat (ticker, 'last');
const average = this.safeFloat (ticker, 'averagePrice');
const last = this.safeFloat2 (ticker, 'last', 'lastTradedPrice');
let symbol = undefined;
const marketId = this.safeString (ticker, 'symbol');
if (marketId !== undefined) {
@@ -404,10 +427,11 @@ module.exports = class kucoin extends Exchange {
symbol = market['symbol'];
}
}
const timestamp = this.safeInteger2 (ticker, 'time', 'datetime');
return {
'symbol': symbol,
'timestamp': undefined,
'datetime': undefined,
'timestamp': timestamp,
'datetime': this.iso8601 (timestamp),
'high': this.safeFloat (ticker, 'high'),
'low': this.safeFloat (ticker, 'low'),
'bid': this.safeFloat (ticker, 'buy'),
@@ -421,7 +445,7 @@ module.exports = class kucoin extends Exchange {
'previousClose': undefined,
'change': this.safeFloat (ticker, 'changePrice'),
'percentage': percentage,
'average': average,
'average': this.safeFloat (ticker, 'averagePrice'),
'baseVolume': this.safeFloat (ticker, 'vol'),
'quoteVolume': this.safeFloat (ticker, 'volValue'),
'info': ticker,
@@ -995,6 +1019,19 @@ module.exports = class kucoin extends Exchange {
// "time":1548848575203567174
// }
//
// {
// sequence: '1568787654360',
// symbol: 'BTC-USDT',
// side: 'buy',
// size: '0.00536577',
// price: '9345',
// takerOrderId: '5e356c4a9f1a790008f8d921',
// time: '1580559434436443257',
// type: 'match',
// makerOrderId: '5e356bffedf0010008fa5d7f',
// tradeId: '5e356c4aeefabd62c62a1ece'
// }
//
// fetchMyTrades (private) v2
//
// {
@@ -1065,10 +1102,7 @@ module.exports = class kucoin extends Exchange {
symbol = market['symbol'];
}
}
let id = this.safeString2 (trade, 'tradeId', 'id');
if (id !== undefined) {
id = id.toString ();
}
const id = this.safeString2 (trade, 'tradeId', 'id');
const orderId = this.safeString (trade, 'orderId');
const takerOrMaker = this.safeString (trade, 'liquidity');
const amount = this.safeFloat2 (trade, 'size', 'amount');
+7 -12
View File
@@ -109,12 +109,9 @@ module.exports = class poloniex extends Exchange {
},
'fees': {
'trading': {
// https://github.com/ccxt/ccxt/issues/6064
// starting from October 21, 2019 17:00 UTC
// all spot trading fees will be reduced to 0.00%
// until December 31, 2019 23:59 UTC
'maker': 0.0,
'taker': 0.0,
// starting from Jan 8 2020
'maker': 0.0009,
'taker': 0.0009,
},
'funding': {},
},
@@ -325,16 +322,14 @@ module.exports = class poloniex extends Exchange {
return orderbook;
}
async fetchOrderBooks (symbols = undefined, params = {}) {
async fetchOrderBooks (symbols = undefined, limit = undefined, params = {}) {
await this.loadMarkets ();
const request = {
'currencyPair': 'all',
};
//
// if (limit !== undefined) {
// request['depth'] = limit; // 100
// }
//
if (limit !== undefined) {
request['depth'] = limit; // 100
}
const response = await this.publicGetReturnOrderBook (this.extend (request, params));
const marketIds = Object.keys (response);
const result = {};
+107 -32
View File
@@ -35,6 +35,7 @@ module.exports = class stex extends Exchange {
'fetchDeposits': true,
'fetchWithdrawals': true,
'withdraw': true,
'fetchFundingFees': true,
},
'version': 'v3',
'urls': {
@@ -499,6 +500,15 @@ module.exports = class stex extends Exchange {
symbol = market['symbol'];
}
const last = this.safeFloat (ticker, 'last');
const open = this.safeFloat (ticker, 'open');
let change = undefined;
let percentage = undefined;
if (last !== undefined) {
if (open !== undefined) {
change = last - open;
percentage = ((100 / open) * last) - 100;
}
}
return {
'symbol': symbol,
'timestamp': timestamp,
@@ -510,12 +520,12 @@ module.exports = class stex extends Exchange {
'ask': this.safeFloat (ticker, 'ask'),
'askVolume': undefined,
'vwap': undefined,
'open': this.safeFloat (ticker, 'open'),
'open': open,
'close': last,
'last': last,
'previousClose': undefined, // previous day close
'change': undefined,
'percentage': undefined,
'change': change,
'percentage': percentage,
'average': undefined,
'baseVolume': this.safeFloat (ticker, 'volumeQuote'),
'quoteVolume': this.safeFloat (ticker, 'volume'),
@@ -1511,7 +1521,7 @@ module.exports = class stex extends Exchange {
if ((code === undefined) && (currency !== undefined)) {
code = currency['code'];
}
const type = ('depositId' in transaction) ? 'deposit' : 'withdrawal';
const type = ('deposit_status_id' in transaction) ? 'deposit' : 'withdrawal';
const amount = this.safeFloat (transaction, 'amount');
const status = this.parseTransactionStatus (this.safeStringLower (transaction, 'status'));
const timestamp = this.safeTimestamp2 (transaction, 'timestamp', 'created_ts');
@@ -1549,21 +1559,20 @@ module.exports = class stex extends Exchange {
}
async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
if (code === undefined) {
throw new ArgumentsRequired (this.id + ' fetchDeposits() requires a currency code argument');
}
await this.loadMarkets ();
const currency = this.currency (code);
const request = {
'currencyTypeName': currency['name'],
// 'pageSize': limit, // documented as required, but it works without it
// 'pageNum': 0, // also works without it, most likely a typo in the docs
// 'sort': 1, // 1 = asc, 0 = desc
};
if (limit !== undefined) {
request['pageSize'] = limit; // default 50
let currency = undefined;
const request = {};
if (code !== undefined) {
currency = this.currency (code);
request['currencyId'] = currency['id'];
}
const response = await this.privatePostExchangeFundControllerWebsiteFundcontrollerGetPayinCoinRecord (this.extend (request, params));
if (limit !== undefined) {
request['limit'] = limit;
}
if (since !== undefined) {
request['timeStart'] = since;
}
const response = await this.profileGetDeposits (this.extend (request, params));
//
// {
// "success": true,
@@ -1583,31 +1592,35 @@ module.exports = class stex extends Exchange {
// "status_color": "#BC3D51",
// "created_at": "2018-11-28 12:32:08",
// "timestamp": "1543409389",
// "confirmations": "1 of 2"
// "confirmations": "1 of 2",
// "protocol_specific_settings": {
// "protocol_name": "Tether OMNI",
// "protocol_id": 10,
// "block_explorer_url": "https://omniexplorer.info/search/"
// }
// }
// ]
// }
//
const deposits = this.safeValue (response, 'datas', {});
const deposits = this.safeValue (response, 'data', []);
return this.parseTransactions (deposits, code, since, limit);
}
async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
if (code === undefined) {
throw new ArgumentsRequired (this.id + ' fetchWithdrawals() requires a currency code argument');
}
await this.loadMarkets ();
const currency = this.currency (code);
const request = {
'currencyId': currency['id'],
// 'pageSize': limit, // documented as required, but it works without it
// 'pageIndex': 0, // also works without it, most likely a typo in the docs
// 'tab': 'all', // all, wait (submitted, not audited), success (auditing passed), fail (auditing failed), cancel (canceled by user)
};
if (limit !== undefined) {
request['pageSize'] = limit; // default 50
let currency = undefined;
const request = {};
if (code !== undefined) {
currency = this.currency (code);
request['currencyId'] = currency['id'];
}
const response = await this.privateGetExchangeFundControllerWebsiteFundwebsitecontrollerGetpayoutcoinrecord (this.extend (request, params));
if (limit !== undefined) {
request['limit'] = limit;
}
if (since !== undefined) {
request['timeStart'] = since;
}
const response = await this.profileGetWithdrawals (this.extend (request, params));
//
// {
// "success": true,
@@ -1638,6 +1651,11 @@ module.exports = class stex extends Exchange {
// "protocol_id": 10,
// "protocol_name": "Tether OMNI",
// "supports_new_address_creation": false
// },
// "protocol_specific_settings": {
// "protocol_name": "Tether OMNI",
// "protocol_id": 10,
// "block_explorer_url": "https://omniexplorer.info/search/"
// }
// }
// ]
@@ -1699,6 +1717,63 @@ module.exports = class stex extends Exchange {
return this.parseTransaction (data, currency);
}
async fetchFundingFees (codes = undefined, params = {}) {
const response = await this.publicGetCurrencies (params);
//
// {
// "success": true,
// "data": [
// {
// "id": 1,
// "code": "BTC",
// "name": "Bitcoin",
// "active": true,
// "delisted": false,
// "precision": 8,
// "minimum_tx_confirmations": 24,
// "minimum_withdrawal_amount": "0.009",
// "minimum_deposit_amount": "0.000003",
// "deposit_fee_currency_id": 1,
// "deposit_fee_currency_code": "ETH",
// "deposit_fee_const": "0.00001",
// "deposit_fee_percent": "0",
// "withdrawal_fee_currency_id": 1,
// "withdrawal_fee_currency_code": "ETH",
// "withdrawal_fee_const": "0.0015",
// "withdrawal_fee_percent": "0",
// "withdrawal_limit": "string",
// "block_explorer_url": "https://blockchain.info/tx/",
// "protocol_specific_settings": [
// {
// "protocol_name": "Tether OMNI",
// "protocol_id": 10,
// "active": true,
// "withdrawal_fee_currency_id": 1,
// "withdrawal_fee_const": 0.002,
// "withdrawal_fee_percent": 0,
// "block_explorer_url": "https://omniexplorer.info/search/"
// }
// ]
// }
// ]
// }
//
const data = this.safeValue (response, 'data', []);
const withdrawFees = {};
const depositFees = {};
for (let i = 0; i < data.length; i++) {
const id = this.safeString (data[i], 'id');
const code = this.safeCurrencyCode (id);
withdrawFees[code] = this.safeFloat (data[i], 'withdrawal_fee_const');
depositFees[code] = this.safeFloat (data[i], 'deposit_fee_const');
}
return {
'withdraw': withdrawFees,
'deposit': depositFees,
'info': response,
};
}
handleErrors (httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
if (response === undefined) {
return; // fallback to default error handler
+61
View File
@@ -0,0 +1,61 @@
'use strict'
// ----------------------------------------------------------------------------
const log = require ('ololog')
, chai = require ('chai')
, assert = chai.assert
// ----------------------------------------------------------------------------
module.exports = (exchange, balance, method) => {
let currencies = [
'USD',
'CNY',
'EUR',
'BTC',
'ETH',
'JPY',
'LTC',
'DASH',
'DOGE',
'UAH',
'RUB',
'XRP',
]
// log.yellow (balance)
assert (typeof balance['total'] === 'object')
assert (typeof balance['free'] === 'object')
assert (typeof balance['used'] === 'object')
for (let currency of Object.keys (balance['total'])) {
let total = balance['total'][currency]
let free = balance['free'][currency]
let used = balance['used'][currency]
if (total !== undefined && free !== undefined && used !== undefined) {
assert (total === free + used, 'free and used do not sum to total ' + exchange.id)
}
}
let result = currencies
.filter (currency => (currency in balance) &&
(balance[currency]['total'] !== undefined))
if (result.length > 0) {
result = result.map (currency => currency + ': ' + balance[currency]['total'])
if (exchange.currencies.length > result.length)
result = result.join (', ') + ' + more...'
else
result = result.join (', ')
} else {
result = 'zero balance'
}
log (result)
}
+7 -62
View File
@@ -2,15 +2,12 @@
// ----------------------------------------------------------------------------
const log = require ('ololog')
, ansi = require ('ansicolor').nice
, chai = require ('chai')
, expect = chai.expect
, assert = chai.assert
const log = require ('ololog')
, testBalance = require ('./test.balance.js')
/* ------------------------------------------------------------------------ */
// ----------------------------------------------------------------------------
module.exports = async (exchange, symbol) => {
module.exports = async (exchange) => {
if (!(exchange.has.fetchBalance)) {
log (exchange.id.green, ' does not have fetchBalance')
@@ -19,61 +16,9 @@ module.exports = async (exchange, symbol) => {
log ('fetching balance...')
let balance = await exchange.fetchBalance ()
const response = await exchange.fetchBalance ()
let currencies = [
'USD',
'CNY',
'EUR',
'BTC',
'ETH',
'JPY',
'LTC',
'DASH',
'DOGE',
'UAH',
'RUB',
'XRP',
]
testBalance (exchange, response)
// log.yellow (balance)
assert (typeof balance['total'] === 'object')
assert (typeof balance['free'] === 'object')
assert (typeof balance['used'] === 'object')
if ('info' in balance) {
for (let currency of Object.keys (balance['total'])) {
let total = balance['total'][currency]
let free = balance['free'][currency]
let used = balance['used'][currency]
if (total !== undefined && free !== undefined && used !== undefined) {
assert (total === free + used, 'free and used do not sum to total ' + exchange.id)
}
}
let result = currencies
.filter (currency => (currency in balance) &&
(balance[currency]['total'] !== undefined))
if (result.length > 0) {
result = result.map (currency => currency + ': ' + balance[currency]['total'])
if (exchange.currencies.length > result.length)
result = result.join (', ') + ' + more...'
else
result = result.join (', ')
} else {
result = 'zero balance'
}
log (result)
} else {
log (exchange.omit (balance, 'info'))
}
return balance
return response
}
+1
View File
@@ -14,6 +14,7 @@ const log = require ('ololog')
module.exports = async (exchange, symbol) => {
const skippedExchanges = [
'btcalpha', // issue with 404 on a documented endpoint https://travis-ci.org/ccxt/ccxt/builds/643930431#L2213
'bitmex', // an issue with null values,to be resolved later
'cex',
'okex',
+3 -5
View File
@@ -17,11 +17,9 @@ const printOrderBookOneLiner = (orderbook, method, symbol) => {
log (symbol.toString ().green,
method,
orderbook['datetime'],
'bid: ' + ((bids.length > 0) ? bids[0][0] : 'N/A'),
'bidVolume: ' + ((bids.length > 0) ? bids[0][1] : 'N/A'),
'ask: ' + ((asks.length > 0) ? asks[0][0] : 'N/A'),
'askVolume: ' + ((asks.length > 0) ? asks[0][1] : 'N/A'))
orderbook['nonce'] || orderbook['datetime'],
bids.length, 'bids:', bids[0],
asks.length, 'asks:', asks[0])
}
/* ------------------------------------------------------------------------ */
+1 -1
View File
@@ -42,7 +42,7 @@ module.exports = (exchange, ticker, method, symbol) => {
assert (!('first' in ticker), '`first` field leftover in ' + exchange.id)
assert (ticker['last'] === ticker['close'], '`last` != `close` in ' + exchange.id)
// log (ticker)
log (ticker['datetime'], exchange.id, method, ticker['symbol'].green, ticker['last'])
keys.forEach (key => assert (key in ticker))
+3
View File
@@ -29,6 +29,9 @@ assert (exchange.parse8601 ('1986-04-26T01:23:47.000Z') === 514862627000);
assert (exchange.parse8601 ('1986-04-26T01:23:47.559Z') === 514862627559);
assert (exchange.parse8601 ('1986-04-26T01:23:47.062Z') === 514862627062);
assert (exchange.parse8601 ('1986-04-26T01:23:47.06Z') === 514862627060);
assert (exchange.parse8601 ('1986-04-26T01:23:47.6Z') === 514862627600);
assert (exchange.parse8601 ('1977-13-13T00:00:00.000Z') === undefined);
assert (exchange.parse8601 ('1986-04-26T25:71:47.000Z') === undefined);
+2
View File
@@ -134,6 +134,8 @@ assert (decimalToPrecision ('0.098765', ROUND, 1, SIGNIFICANT_DIGITS, PAD_WITH_Z
assert (decimalToPrecision ('0', ROUND, 0, SIGNIFICANT_DIGITS) === '0');
assert (decimalToPrecision ('-0.123', ROUND, 0, SIGNIFICANT_DIGITS) === '0');
assert (decimalToPrecision ('0.00000044', ROUND, 5, SIGNIFICANT_DIGITS) === '0.00000044');
// ----------------------------------------------------------------------------
// testDecimalToPrecisionRoundingToTickSize
+3 -8
View File
@@ -9,13 +9,11 @@ const debug = process.argv.includes ('--debug') || false
/* ------------------------------------------------------------------------ */
const asTable = require ('as-table')
, util = require ('util')
, log = require ('ololog')
, ansi = require ('ansicolor').nice
, fs = require ('fs')
, ccxt = require ('../../ccxt.js')
, chai = require ('chai')
, expect = chai.expect
, assert = chai.assert
/* ------------------------------------------------------------------------ */
@@ -82,14 +80,12 @@ Object.keys (errors)
const keysGlobal = 'keys.json'
const keysLocal = 'keys.local.json'
let keysFile = fs.existsSync (keysLocal) ? keysLocal : keysGlobal
const keysFile = fs.existsSync (keysLocal) ? keysLocal : keysGlobal
// eslint-disable-next-line import/no-dynamic-require
let settings = require (__dirname + '/../../' + keysFile)[exchangeId]
const settings = require (__dirname + '/../../' + keysFile)[exchangeId]
if (settings) {
const keys = Object.keys (settings)
for (let i = 0; i < keys.length; i++) {
const key = keys[i]
for (const key in settings) {
if (settings[key]) {
settings[key] = ccxt.deepExtend (exchange[key] || {}, settings[key])
}
@@ -224,7 +220,6 @@ let testExchange = async exchange => {
await loadExchange (exchange)
let delay = exchange.rateLimit
let symbol = exchange.symbols[0]
const symbols = [
'BTC/USD',
+8 -2
View File
@@ -281,7 +281,7 @@ module.exports = class tidex extends Exchange {
return this.parseOrderBook (orderbook);
}
async fetchOrderBooks (symbols = undefined, params = {}) {
async fetchOrderBooks (symbols = undefined, limit = undefined, params = {}) {
await this.loadMarkets ();
let ids = undefined;
if (symbols === undefined) {
@@ -298,6 +298,9 @@ module.exports = class tidex extends Exchange {
const request = {
'pair': ids,
};
if (limit !== undefined) {
request['limit'] = limit; // default = 150, max = 2000
}
const response = await this.publicGetDepthPair (this.extend (request, params));
const result = {};
ids = Object.keys (response);
@@ -324,10 +327,13 @@ module.exports = class tidex extends Exchange {
// sell: 0.03377798,
// updated: 1537522009 }
//
const timestamp = this.safeTimestamp (ticker, 'updated');
let timestamp = this.safeTimestamp (ticker, 'updated');
let symbol = undefined;
if (market !== undefined) {
symbol = market['symbol'];
if (!market['active']) {
timestamp = undefined;
}
}
const last = this.safeFloat (ticker, 'last');
return {
+2 -2
View File
@@ -442,7 +442,7 @@ module.exports = class upbit extends Exchange {
return base + '/' + quote;
}
async fetchOrderBooks (symbols = undefined, params = {}) {
async fetchOrderBooks (symbols = undefined, limit = undefined, params = {}) {
await this.loadMarkets ();
let ids = undefined;
if (symbols === undefined) {
@@ -505,7 +505,7 @@ module.exports = class upbit extends Exchange {
}
async fetchOrderBook (symbol, limit = undefined, params = {}) {
const orderbooks = await this.fetchOrderBooks ([ symbol ], params);
const orderbooks = await this.fetchOrderBooks ([ symbol ], limit, params);
return this.safeValue (orderbooks, symbol);
}
+5 -1
View File
@@ -295,7 +295,7 @@ module.exports = class yobit extends Exchange {
return this.parseOrderBook (orderbook);
}
async fetchOrderBooks (symbols = undefined, params = {}) {
async fetchOrderBooks (symbols = undefined, limit = undefined, params = {}) {
await this.loadMarkets ();
let ids = undefined;
if (symbols === undefined) {
@@ -311,7 +311,11 @@ module.exports = class yobit extends Exchange {
}
const request = {
'pair': ids,
// 'ignore_invalid': true,
};
if (limit !== undefined) {
request['limit'] = limit;
}
const response = await this.publicGetDepthPair (this.extend (request, params));
const result = {};
ids = Object.keys (response);
+11 -11
View File
@@ -1,27 +1,27 @@
{
"_from": "ccxt",
"_id": "ccxt@1.21.82",
"_from": "ccxt@1.22.39",
"_id": "ccxt@1.22.39",
"_inBundle": false,
"_integrity": "sha512-+HX/6WK8BM5c9OwhALl9zzMKvueZfHDXVmfrKNmQ4005hc+BtNuNe47XEs6dAylY+ll7n9JpzaoIZhy6Lipiew==",
"_integrity": "sha512-Vq4BzYS/FwRudPKQ6BQGU3SVntYv7EAQGT+2guf+e7qm45CJMhdoVwR1z89kl42fbK39XMnl8sUnRCwsKPs38A==",
"_location": "/ccxt",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"type": "version",
"registry": true,
"raw": "ccxt",
"raw": "ccxt@1.22.39",
"name": "ccxt",
"escapedName": "ccxt",
"rawSpec": "",
"rawSpec": "1.22.39",
"saveSpec": null,
"fetchSpec": "latest"
"fetchSpec": "1.22.39"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/ccxt/-/ccxt-1.21.82.tgz",
"_shasum": "6117f2d436d053c66574eaae195083fb69d64903",
"_spec": "ccxt",
"_resolved": "https://registry.npmjs.org/ccxt/-/ccxt-1.22.39.tgz",
"_shasum": "ca28a2dafd94089238279c9e5f2f4a041348d065",
"_spec": "ccxt@1.22.39",
"_where": "C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer",
"author": {
"name": "Igor Kroitor",
@@ -520,5 +520,5 @@
},
"types": "./ccxt.d.ts",
"unpkg": "dist/ccxt.browser.js",
"version": "1.21.82"
"version": "1.22.39"
}
+912
View File
@@ -0,0 +1,912 @@
"use strict";
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
(function (f) {
if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === "object" && typeof module !== "undefined") {
module.exports = f();
} else if (typeof define === "function" && define.amd) {
define([], f);
} else {
var g;
if (typeof window !== "undefined") {
g = window;
} else if (typeof global !== "undefined") {
g = global;
} else if (typeof self !== "undefined") {
g = self;
} else {
g = this;
}
g.debug = f();
}
})(function () {
var define, module, exports;
return function () {
function r(e, n, t) {
function o(i, f) {
if (!n[i]) {
if (!e[i]) {
var c = "function" == typeof require && require;
if (!f && c) return c(i, !0);
if (u) return u(i, !0);
var a = new Error("Cannot find module '" + i + "'");
throw a.code = "MODULE_NOT_FOUND", a;
}
var p = n[i] = {
exports: {}
};
e[i][0].call(p.exports, function (r) {
var n = e[i][1][r];
return o(n || r);
}, p, p.exports, r, e, n, t);
}
return n[i].exports;
}
for (var u = "function" == typeof require && require, i = 0; i < t.length; i++) {
o(t[i]);
}
return o;
}
return r;
}()({
1: [function (require, module, exports) {
/**
* Helpers.
*/
var s = 1000;
var m = s * 60;
var h = m * 60;
var d = h * 24;
var w = d * 7;
var y = d * 365.25;
/**
* Parse or format the given `val`.
*
* Options:
*
* - `long` verbose formatting [false]
*
* @param {String|Number} val
* @param {Object} [options]
* @throws {Error} throw an error if val is not a non-empty string or a number
* @return {String|Number}
* @api public
*/
module.exports = function (val, options) {
options = options || {};
var type = _typeof(val);
if (type === 'string' && val.length > 0) {
return parse(val);
} else if (type === 'number' && isNaN(val) === false) {
return options.long ? fmtLong(val) : fmtShort(val);
}
throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val));
};
/**
* Parse the given `str` and return milliseconds.
*
* @param {String} str
* @return {Number}
* @api private
*/
function parse(str) {
str = String(str);
if (str.length > 100) {
return;
}
var match = /^((?:\d+)?\-?\d?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(str);
if (!match) {
return;
}
var n = parseFloat(match[1]);
var type = (match[2] || 'ms').toLowerCase();
switch (type) {
case 'years':
case 'year':
case 'yrs':
case 'yr':
case 'y':
return n * y;
case 'weeks':
case 'week':
case 'w':
return n * w;
case 'days':
case 'day':
case 'd':
return n * d;
case 'hours':
case 'hour':
case 'hrs':
case 'hr':
case 'h':
return n * h;
case 'minutes':
case 'minute':
case 'mins':
case 'min':
case 'm':
return n * m;
case 'seconds':
case 'second':
case 'secs':
case 'sec':
case 's':
return n * s;
case 'milliseconds':
case 'millisecond':
case 'msecs':
case 'msec':
case 'ms':
return n;
default:
return undefined;
}
}
/**
* Short format for `ms`.
*
* @param {Number} ms
* @return {String}
* @api private
*/
function fmtShort(ms) {
var msAbs = Math.abs(ms);
if (msAbs >= d) {
return Math.round(ms / d) + 'd';
}
if (msAbs >= h) {
return Math.round(ms / h) + 'h';
}
if (msAbs >= m) {
return Math.round(ms / m) + 'm';
}
if (msAbs >= s) {
return Math.round(ms / s) + 's';
}
return ms + 'ms';
}
/**
* Long format for `ms`.
*
* @param {Number} ms
* @return {String}
* @api private
*/
function fmtLong(ms) {
var msAbs = Math.abs(ms);
if (msAbs >= d) {
return plural(ms, msAbs, d, 'day');
}
if (msAbs >= h) {
return plural(ms, msAbs, h, 'hour');
}
if (msAbs >= m) {
return plural(ms, msAbs, m, 'minute');
}
if (msAbs >= s) {
return plural(ms, msAbs, s, 'second');
}
return ms + ' ms';
}
/**
* Pluralization helper.
*/
function plural(ms, msAbs, n, name) {
var isPlural = msAbs >= n * 1.5;
return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
}
}, {}],
2: [function (require, module, exports) {
// shim for using process in browser
var process = module.exports = {}; // cached from whatever global is present so that test runners that stub it
// don't break things. But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals. It's inside a
// function because try/catches deoptimize in certain engines.
var cachedSetTimeout;
var cachedClearTimeout;
function defaultSetTimout() {
throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout() {
throw new Error('clearTimeout has not been defined');
}
(function () {
try {
if (typeof setTimeout === 'function') {
cachedSetTimeout = setTimeout;
} else {
cachedSetTimeout = defaultSetTimout;
}
} catch (e) {
cachedSetTimeout = defaultSetTimout;
}
try {
if (typeof clearTimeout === 'function') {
cachedClearTimeout = clearTimeout;
} else {
cachedClearTimeout = defaultClearTimeout;
}
} catch (e) {
cachedClearTimeout = defaultClearTimeout;
}
})();
function runTimeout(fun) {
if (cachedSetTimeout === setTimeout) {
//normal enviroments in sane situations
return setTimeout(fun, 0);
} // if setTimeout wasn't available but was latter defined
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
cachedSetTimeout = setTimeout;
return setTimeout(fun, 0);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedSetTimeout(fun, 0);
} catch (e) {
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedSetTimeout.call(null, fun, 0);
} catch (e) {
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
return cachedSetTimeout.call(this, fun, 0);
}
}
}
function runClearTimeout(marker) {
if (cachedClearTimeout === clearTimeout) {
//normal enviroments in sane situations
return clearTimeout(marker);
} // if clearTimeout wasn't available but was latter defined
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
cachedClearTimeout = clearTimeout;
return clearTimeout(marker);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedClearTimeout(marker);
} catch (e) {
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedClearTimeout.call(null, marker);
} catch (e) {
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
return cachedClearTimeout.call(this, marker);
}
}
}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
if (!draining || !currentQueue) {
return;
}
draining = false;
if (currentQueue.length) {
queue = currentQueue.concat(queue);
} else {
queueIndex = -1;
}
if (queue.length) {
drainQueue();
}
}
function drainQueue() {
if (draining) {
return;
}
var timeout = runTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while (len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
if (currentQueue) {
currentQueue[queueIndex].run();
}
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
runClearTimeout(timeout);
}
process.nextTick = function (fun) {
var args = new Array(arguments.length - 1);
if (arguments.length > 1) {
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
}
queue.push(new Item(fun, args));
if (queue.length === 1 && !draining) {
runTimeout(drainQueue);
}
}; // v8 likes predictible objects
function Item(fun, array) {
this.fun = fun;
this.array = array;
}
Item.prototype.run = function () {
this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;
process.listeners = function (name) {
return [];
};
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
process.cwd = function () {
return '/';
};
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function () {
return 0;
};
}, {}],
3: [function (require, module, exports) {
/**
* This is the common logic for both the Node.js and web browser
* implementations of `debug()`.
*/
function setup(env) {
createDebug.debug = createDebug;
createDebug.default = createDebug;
createDebug.coerce = coerce;
createDebug.disable = disable;
createDebug.enable = enable;
createDebug.enabled = enabled;
createDebug.humanize = require('ms');
Object.keys(env).forEach(function (key) {
createDebug[key] = env[key];
});
/**
* Active `debug` instances.
*/
createDebug.instances = [];
/**
* The currently active debug mode names, and names to skip.
*/
createDebug.names = [];
createDebug.skips = [];
/**
* Map of special "%n" handling functions, for the debug "format" argument.
*
* Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
*/
createDebug.formatters = {};
/**
* Selects a color for a debug namespace
* @param {String} namespace The namespace string for the for the debug instance to be colored
* @return {Number|String} An ANSI color code for the given namespace
* @api private
*/
function selectColor(namespace) {
var hash = 0;
for (var i = 0; i < namespace.length; i++) {
hash = (hash << 5) - hash + namespace.charCodeAt(i);
hash |= 0; // Convert to 32bit integer
}
return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
}
createDebug.selectColor = selectColor;
/**
* Create a debugger with the given `namespace`.
*
* @param {String} namespace
* @return {Function}
* @api public
*/
function createDebug(namespace) {
var prevTime;
function debug() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
// Disabled?
if (!debug.enabled) {
return;
}
var self = debug; // Set `diff` timestamp
var curr = Number(new Date());
var ms = curr - (prevTime || curr);
self.diff = ms;
self.prev = prevTime;
self.curr = curr;
prevTime = curr;
args[0] = createDebug.coerce(args[0]);
if (typeof args[0] !== 'string') {
// Anything else let's inspect with %O
args.unshift('%O');
} // Apply any `formatters` transformations
var index = 0;
args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) {
// If we encounter an escaped % then don't increase the array index
if (match === '%%') {
return match;
}
index++;
var formatter = createDebug.formatters[format];
if (typeof formatter === 'function') {
var val = args[index];
match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format`
args.splice(index, 1);
index--;
}
return match;
}); // Apply env-specific formatting (colors, etc.)
createDebug.formatArgs.call(self, args);
var logFn = self.log || createDebug.log;
logFn.apply(self, args);
}
debug.namespace = namespace;
debug.enabled = createDebug.enabled(namespace);
debug.useColors = createDebug.useColors();
debug.color = selectColor(namespace);
debug.destroy = destroy;
debug.extend = extend; // Debug.formatArgs = formatArgs;
// debug.rawLog = rawLog;
// env-specific initialization logic for debug instances
if (typeof createDebug.init === 'function') {
createDebug.init(debug);
}
createDebug.instances.push(debug);
return debug;
}
function destroy() {
var index = createDebug.instances.indexOf(this);
if (index !== -1) {
createDebug.instances.splice(index, 1);
return true;
}
return false;
}
function extend(namespace, delimiter) {
var newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
newDebug.log = this.log;
return newDebug;
}
/**
* Enables a debug mode by namespaces. This can include modes
* separated by a colon and wildcards.
*
* @param {String} namespaces
* @api public
*/
function enable(namespaces) {
createDebug.save(namespaces);
createDebug.names = [];
createDebug.skips = [];
var i;
var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
var len = split.length;
for (i = 0; i < len; i++) {
if (!split[i]) {
// ignore empty strings
continue;
}
namespaces = split[i].replace(/\*/g, '.*?');
if (namespaces[0] === '-') {
createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
} else {
createDebug.names.push(new RegExp('^' + namespaces + '$'));
}
}
for (i = 0; i < createDebug.instances.length; i++) {
var instance = createDebug.instances[i];
instance.enabled = createDebug.enabled(instance.namespace);
}
}
/**
* Disable debug output.
*
* @return {String} namespaces
* @api public
*/
function disable() {
var namespaces = [].concat(_toConsumableArray(createDebug.names.map(toNamespace)), _toConsumableArray(createDebug.skips.map(toNamespace).map(function (namespace) {
return '-' + namespace;
}))).join(',');
createDebug.enable('');
return namespaces;
}
/**
* Returns true if the given mode name is enabled, false otherwise.
*
* @param {String} name
* @return {Boolean}
* @api public
*/
function enabled(name) {
if (name[name.length - 1] === '*') {
return true;
}
var i;
var len;
for (i = 0, len = createDebug.skips.length; i < len; i++) {
if (createDebug.skips[i].test(name)) {
return false;
}
}
for (i = 0, len = createDebug.names.length; i < len; i++) {
if (createDebug.names[i].test(name)) {
return true;
}
}
return false;
}
/**
* Convert regexp to namespace
*
* @param {RegExp} regxep
* @return {String} namespace
* @api private
*/
function toNamespace(regexp) {
return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\.\*\?$/, '*');
}
/**
* Coerce `val`.
*
* @param {Mixed} val
* @return {Mixed}
* @api private
*/
function coerce(val) {
if (val instanceof Error) {
return val.stack || val.message;
}
return val;
}
createDebug.enable(createDebug.load());
return createDebug;
}
module.exports = setup;
}, {
"ms": 1
}],
4: [function (require, module, exports) {
(function (process) {
/* eslint-env browser */
/**
* This is the web browser implementation of `debug()`.
*/
exports.log = log;
exports.formatArgs = formatArgs;
exports.save = save;
exports.load = load;
exports.useColors = useColors;
exports.storage = localstorage();
/**
* Colors.
*/
exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33'];
/**
* Currently only WebKit-based Web Inspectors, Firefox >= v31,
* and the Firebug extension (any Firefox version) are known
* to support "%c" CSS customizations.
*
* TODO: add a `localStorage` variable to explicitly enable/disable colors
*/
// eslint-disable-next-line complexity
function useColors() {
// NB: In an Electron preload script, document will be defined but not fully
// initialized. Since we know we're in Chrome, we'll just detect this case
// explicitly
if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
return true;
} // Internet Explorer and Edge do not support colors.
if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
return false;
} // Is webkit? http://stackoverflow.com/a/16459606/376773
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773
typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker
typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
}
/**
* Colorize log arguments if enabled.
*
* @api public
*/
function formatArgs(args) {
args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff);
if (!this.useColors) {
return;
}
var c = 'color: ' + this.color;
args.splice(1, 0, c, 'color: inherit'); // The final "%c" is somewhat tricky, because there could be other
// arguments passed either before or after the %c, so we need to
// figure out the correct index to insert the CSS into
var index = 0;
var lastC = 0;
args[0].replace(/%[a-zA-Z%]/g, function (match) {
if (match === '%%') {
return;
}
index++;
if (match === '%c') {
// We only are interested in the *last* %c
// (the user may have provided their own)
lastC = index;
}
});
args.splice(lastC, 0, c);
}
/**
* Invokes `console.log()` when available.
* No-op when `console.log` is not a "function".
*
* @api public
*/
function log() {
var _console;
// This hackery is required for IE8/9, where
// the `console.log` function doesn't have 'apply'
return (typeof console === "undefined" ? "undefined" : _typeof(console)) === 'object' && console.log && (_console = console).log.apply(_console, arguments);
}
/**
* Save `namespaces`.
*
* @param {String} namespaces
* @api private
*/
function save(namespaces) {
try {
if (namespaces) {
exports.storage.setItem('debug', namespaces);
} else {
exports.storage.removeItem('debug');
}
} catch (error) {// Swallow
// XXX (@Qix-) should we be logging these?
}
}
/**
* Load `namespaces`.
*
* @return {String} returns the previously persisted debug modes
* @api private
*/
function load() {
var r;
try {
r = exports.storage.getItem('debug');
} catch (error) {} // Swallow
// XXX (@Qix-) should we be logging these?
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
if (!r && typeof process !== 'undefined' && 'env' in process) {
r = process.env.DEBUG;
}
return r;
}
/**
* Localstorage attempts to return the localstorage.
*
* This is necessary because safari throws
* when a user disables cookies/localstorage
* and you attempt to access it.
*
* @return {LocalStorage}
* @api private
*/
function localstorage() {
try {
// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
// The Browser also has localStorage in the global context.
return localStorage;
} catch (error) {// Swallow
// XXX (@Qix-) should we be logging these?
}
}
module.exports = require('./common')(exports);
var formatters = module.exports.formatters;
/**
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
*/
formatters.j = function (v) {
try {
return JSON.stringify(v);
} catch (error) {
return '[UnexpectedJSONParseError]: ' + error.message;
}
};
}).call(this, require('_process'));
}, {
"./common": 3,
"_process": 2
}]
}, {}, [4])(4);
});
+43 -26
View File
@@ -1,32 +1,27 @@
{
"_args": [
[
"debug@3.1.0",
"C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer"
]
],
"_from": "debug@3.1.0",
"_id": "debug@3.1.0",
"_from": "debug@^4.0.1",
"_id": "debug@4.1.1",
"_inBundle": false,
"_integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"_integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"_location": "/debug",
"_phantomChildren": {},
"_requested": {
"type": "version",
"type": "range",
"registry": true,
"raw": "debug@3.1.0",
"raw": "debug@^4.0.1",
"name": "debug",
"escapedName": "debug",
"rawSpec": "3.1.0",
"rawSpec": "^4.0.1",
"saveSpec": null,
"fetchSpec": "3.1.0"
"fetchSpec": "^4.0.1"
},
"_requiredBy": [
"/follow-redirects"
"/telegraf"
],
"_resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"_spec": "3.1.0",
"_where": "C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer",
"_resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"_shasum": "3b72260255109c6b589cee050f1d516139664791",
"_spec": "debug@^4.0.1",
"_where": "C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer\\node_modules\\telegraf",
"author": {
"name": "TJ Holowaychuk",
"email": "tj@vision-media.ca"
@@ -35,6 +30,7 @@
"bugs": {
"url": "https://github.com/visionmedia/debug/issues"
},
"bundleDependencies": false,
"contributors": [
{
"name": "Nathan Rajlich",
@@ -47,27 +43,34 @@
}
],
"dependencies": {
"ms": "2.0.0"
"ms": "^2.1.1"
},
"deprecated": false,
"description": "small debugging utility",
"devDependencies": {
"@babel/cli": "^7.0.0",
"@babel/core": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"browserify": "14.4.0",
"chai": "^3.5.0",
"concurrently": "^3.1.0",
"coveralls": "^2.11.15",
"eslint": "^3.12.1",
"coveralls": "^3.0.2",
"istanbul": "^0.4.5",
"karma": "^1.3.0",
"karma": "^3.0.0",
"karma-chai": "^0.1.0",
"karma-mocha": "^1.3.0",
"karma-phantomjs-launcher": "^1.0.2",
"karma-sinon": "^1.0.5",
"mocha": "^3.2.0",
"mocha": "^5.2.0",
"mocha-lcov-reporter": "^1.2.0",
"rimraf": "^2.5.4",
"sinon": "^1.17.6",
"sinon-chai": "^2.8.0"
"xo": "^0.23.0"
},
"files": [
"src",
"dist/debug.js",
"LICENSE",
"README.md"
],
"homepage": "https://github.com/visionmedia/debug#readme",
"keywords": [
"debug",
@@ -81,5 +84,19 @@
"type": "git",
"url": "git://github.com/visionmedia/debug.git"
},
"version": "3.1.0"
"scripts": {
"build": "npm run build:debug && npm run build:test",
"build:debug": "babel -o dist/debug.js dist/debug.es6.js > dist/debug.js",
"build:test": "babel -d dist test.js",
"clean": "rimraf dist coverage",
"lint": "xo",
"prebuild:debug": "mkdir -p dist && browserify --standalone debug -o dist/debug.es6.js .",
"pretest:browser": "npm run build",
"test": "npm run test:node && npm run test:browser",
"test:browser": "karma start --single-run",
"test:coverage": "cat ./coverage/lcov.info | coveralls",
"test:node": "istanbul cover _mocha -- test.js"
},
"unpkg": "./dist/debug.js",
"version": "4.1.1"
}
+180 -111
View File
@@ -1,36 +1,97 @@
/* eslint-env browser */
/**
* This is the web browser implementation of `debug()`.
*
* Expose `debug()` as the module.
*/
exports = module.exports = require('./debug');
exports.log = log;
exports.formatArgs = formatArgs;
exports.save = save;
exports.load = load;
exports.useColors = useColors;
exports.storage = 'undefined' != typeof chrome
&& 'undefined' != typeof chrome.storage
? chrome.storage.local
: localstorage();
exports.storage = localstorage();
/**
* Colors.
*/
exports.colors = [
'#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC',
'#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF',
'#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC',
'#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF',
'#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC',
'#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033',
'#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366',
'#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933',
'#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC',
'#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF',
'#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33'
'#0000CC',
'#0000FF',
'#0033CC',
'#0033FF',
'#0066CC',
'#0066FF',
'#0099CC',
'#0099FF',
'#00CC00',
'#00CC33',
'#00CC66',
'#00CC99',
'#00CCCC',
'#00CCFF',
'#3300CC',
'#3300FF',
'#3333CC',
'#3333FF',
'#3366CC',
'#3366FF',
'#3399CC',
'#3399FF',
'#33CC00',
'#33CC33',
'#33CC66',
'#33CC99',
'#33CCCC',
'#33CCFF',
'#6600CC',
'#6600FF',
'#6633CC',
'#6633FF',
'#66CC00',
'#66CC33',
'#9900CC',
'#9900FF',
'#9933CC',
'#9933FF',
'#99CC00',
'#99CC33',
'#CC0000',
'#CC0033',
'#CC0066',
'#CC0099',
'#CC00CC',
'#CC00FF',
'#CC3300',
'#CC3333',
'#CC3366',
'#CC3399',
'#CC33CC',
'#CC33FF',
'#CC6600',
'#CC6633',
'#CC9900',
'#CC9933',
'#CCCC00',
'#CCCC33',
'#FF0000',
'#FF0033',
'#FF0066',
'#FF0099',
'#FF00CC',
'#FF00FF',
'#FF3300',
'#FF3333',
'#FF3366',
'#FF3399',
'#FF33CC',
'#FF33FF',
'#FF6600',
'#FF6633',
'#FF9900',
'#FF9933',
'#FFCC00',
'#FFCC33'
];
/**
@@ -41,44 +102,32 @@ exports.colors = [
* TODO: add a `localStorage` variable to explicitly enable/disable colors
*/
// eslint-disable-next-line complexity
function useColors() {
// NB: In an Electron preload script, document will be defined but not fully
// initialized. Since we know we're in Chrome, we'll just detect this case
// explicitly
if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') {
return true;
}
// NB: In an Electron preload script, document will be defined but not fully
// initialized. Since we know we're in Chrome, we'll just detect this case
// explicitly
if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
return true;
}
// Internet Explorer and Edge do not support colors.
if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
return false;
}
// Internet Explorer and Edge do not support colors.
if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
return false;
}
// is webkit? http://stackoverflow.com/a/16459606/376773
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
// is firebug? http://stackoverflow.com/a/398120/376773
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
// is firefox >= v31?
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
// double check webkit in userAgent just in case we are in a worker
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
// Is webkit? http://stackoverflow.com/a/16459606/376773
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
// Is firebug? http://stackoverflow.com/a/398120/376773
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
// Is firefox >= v31?
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
// Double check webkit in userAgent just in case we are in a worker
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
}
/**
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
*/
exports.formatters.j = function(v) {
try {
return JSON.stringify(v);
} catch (err) {
return '[UnexpectedJSONParseError]: ' + err.message;
}
};
/**
* Colorize log arguments if enabled.
*
@@ -86,36 +135,38 @@ exports.formatters.j = function(v) {
*/
function formatArgs(args) {
var useColors = this.useColors;
args[0] = (this.useColors ? '%c' : '') +
this.namespace +
(this.useColors ? ' %c' : ' ') +
args[0] +
(this.useColors ? '%c ' : ' ') +
'+' + module.exports.humanize(this.diff);
args[0] = (useColors ? '%c' : '')
+ this.namespace
+ (useColors ? ' %c' : ' ')
+ args[0]
+ (useColors ? '%c ' : ' ')
+ '+' + exports.humanize(this.diff);
if (!this.useColors) {
return;
}
if (!useColors) return;
const c = 'color: ' + this.color;
args.splice(1, 0, c, 'color: inherit');
var c = 'color: ' + this.color;
args.splice(1, 0, c, 'color: inherit')
// The final "%c" is somewhat tricky, because there could be other
// arguments passed either before or after the %c, so we need to
// figure out the correct index to insert the CSS into
let index = 0;
let lastC = 0;
args[0].replace(/%[a-zA-Z%]/g, match => {
if (match === '%%') {
return;
}
index++;
if (match === '%c') {
// We only are interested in the *last* %c
// (the user may have provided their own)
lastC = index;
}
});
// the final "%c" is somewhat tricky, because there could be other
// arguments passed either before or after the %c, so we need to
// figure out the correct index to insert the CSS into
var index = 0;
var lastC = 0;
args[0].replace(/%[a-zA-Z%]/g, function(match) {
if ('%%' === match) return;
index++;
if ('%c' === match) {
// we only are interested in the *last* %c
// (the user may have provided their own)
lastC = index;
}
});
args.splice(lastC, 0, c);
args.splice(lastC, 0, c);
}
/**
@@ -124,13 +175,12 @@ function formatArgs(args) {
*
* @api public
*/
function log() {
// this hackery is required for IE8/9, where
// the `console.log` function doesn't have 'apply'
return 'object' === typeof console
&& console.log
&& Function.prototype.apply.call(console.log, console, arguments);
function log(...args) {
// This hackery is required for IE8/9, where
// the `console.log` function doesn't have 'apply'
return typeof console === 'object' &&
console.log &&
console.log(...args);
}
/**
@@ -139,15 +189,17 @@ function log() {
* @param {String} namespaces
* @api private
*/
function save(namespaces) {
try {
if (null == namespaces) {
exports.storage.removeItem('debug');
} else {
exports.storage.debug = namespaces;
}
} catch(e) {}
try {
if (namespaces) {
exports.storage.setItem('debug', namespaces);
} else {
exports.storage.removeItem('debug');
}
} catch (error) {
// Swallow
// XXX (@Qix-) should we be logging these?
}
}
/**
@@ -156,27 +208,23 @@ function save(namespaces) {
* @return {String} returns the previously persisted debug modes
* @api private
*/
function load() {
var r;
try {
r = exports.storage.debug;
} catch(e) {}
let r;
try {
r = exports.storage.getItem('debug');
} catch (error) {
// Swallow
// XXX (@Qix-) should we be logging these?
}
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
if (!r && typeof process !== 'undefined' && 'env' in process) {
r = process.env.DEBUG;
}
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
if (!r && typeof process !== 'undefined' && 'env' in process) {
r = process.env.DEBUG;
}
return r;
return r;
}
/**
* Enable namespaces listed in `localStorage.debug` initially.
*/
exports.enable(load());
/**
* Localstorage attempts to return the localstorage.
*
@@ -189,7 +237,28 @@ exports.enable(load());
*/
function localstorage() {
try {
return window.localStorage;
} catch (e) {}
try {
// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
// The Browser also has localStorage in the global context.
return localStorage;
} catch (error) {
// Swallow
// XXX (@Qix-) should we be logging these?
}
}
module.exports = require('./common')(exports);
const {formatters} = module.exports;
/**
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
*/
formatters.j = function (v) {
try {
return JSON.stringify(v);
} catch (error) {
return '[UnexpectedJSONParseError]: ' + error.message;
}
};
+266
View File
@@ -0,0 +1,266 @@
/**
* This is the common logic for both the Node.js and web browser
* implementations of `debug()`.
*/
function setup(env) {
createDebug.debug = createDebug;
createDebug.default = createDebug;
createDebug.coerce = coerce;
createDebug.disable = disable;
createDebug.enable = enable;
createDebug.enabled = enabled;
createDebug.humanize = require('ms');
Object.keys(env).forEach(key => {
createDebug[key] = env[key];
});
/**
* Active `debug` instances.
*/
createDebug.instances = [];
/**
* The currently active debug mode names, and names to skip.
*/
createDebug.names = [];
createDebug.skips = [];
/**
* Map of special "%n" handling functions, for the debug "format" argument.
*
* Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
*/
createDebug.formatters = {};
/**
* Selects a color for a debug namespace
* @param {String} namespace The namespace string for the for the debug instance to be colored
* @return {Number|String} An ANSI color code for the given namespace
* @api private
*/
function selectColor(namespace) {
let hash = 0;
for (let i = 0; i < namespace.length; i++) {
hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
hash |= 0; // Convert to 32bit integer
}
return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
}
createDebug.selectColor = selectColor;
/**
* Create a debugger with the given `namespace`.
*
* @param {String} namespace
* @return {Function}
* @api public
*/
function createDebug(namespace) {
let prevTime;
function debug(...args) {
// Disabled?
if (!debug.enabled) {
return;
}
const self = debug;
// Set `diff` timestamp
const curr = Number(new Date());
const ms = curr - (prevTime || curr);
self.diff = ms;
self.prev = prevTime;
self.curr = curr;
prevTime = curr;
args[0] = createDebug.coerce(args[0]);
if (typeof args[0] !== 'string') {
// Anything else let's inspect with %O
args.unshift('%O');
}
// Apply any `formatters` transformations
let index = 0;
args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
// If we encounter an escaped % then don't increase the array index
if (match === '%%') {
return match;
}
index++;
const formatter = createDebug.formatters[format];
if (typeof formatter === 'function') {
const val = args[index];
match = formatter.call(self, val);
// Now we need to remove `args[index]` since it's inlined in the `format`
args.splice(index, 1);
index--;
}
return match;
});
// Apply env-specific formatting (colors, etc.)
createDebug.formatArgs.call(self, args);
const logFn = self.log || createDebug.log;
logFn.apply(self, args);
}
debug.namespace = namespace;
debug.enabled = createDebug.enabled(namespace);
debug.useColors = createDebug.useColors();
debug.color = selectColor(namespace);
debug.destroy = destroy;
debug.extend = extend;
// Debug.formatArgs = formatArgs;
// debug.rawLog = rawLog;
// env-specific initialization logic for debug instances
if (typeof createDebug.init === 'function') {
createDebug.init(debug);
}
createDebug.instances.push(debug);
return debug;
}
function destroy() {
const index = createDebug.instances.indexOf(this);
if (index !== -1) {
createDebug.instances.splice(index, 1);
return true;
}
return false;
}
function extend(namespace, delimiter) {
const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
newDebug.log = this.log;
return newDebug;
}
/**
* Enables a debug mode by namespaces. This can include modes
* separated by a colon and wildcards.
*
* @param {String} namespaces
* @api public
*/
function enable(namespaces) {
createDebug.save(namespaces);
createDebug.names = [];
createDebug.skips = [];
let i;
const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
const len = split.length;
for (i = 0; i < len; i++) {
if (!split[i]) {
// ignore empty strings
continue;
}
namespaces = split[i].replace(/\*/g, '.*?');
if (namespaces[0] === '-') {
createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
} else {
createDebug.names.push(new RegExp('^' + namespaces + '$'));
}
}
for (i = 0; i < createDebug.instances.length; i++) {
const instance = createDebug.instances[i];
instance.enabled = createDebug.enabled(instance.namespace);
}
}
/**
* Disable debug output.
*
* @return {String} namespaces
* @api public
*/
function disable() {
const namespaces = [
...createDebug.names.map(toNamespace),
...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace)
].join(',');
createDebug.enable('');
return namespaces;
}
/**
* Returns true if the given mode name is enabled, false otherwise.
*
* @param {String} name
* @return {Boolean}
* @api public
*/
function enabled(name) {
if (name[name.length - 1] === '*') {
return true;
}
let i;
let len;
for (i = 0, len = createDebug.skips.length; i < len; i++) {
if (createDebug.skips[i].test(name)) {
return false;
}
}
for (i = 0, len = createDebug.names.length; i < len; i++) {
if (createDebug.names[i].test(name)) {
return true;
}
}
return false;
}
/**
* Convert regexp to namespace
*
* @param {RegExp} regxep
* @return {String} namespace
* @api private
*/
function toNamespace(regexp) {
return regexp.toString()
.substring(2, regexp.toString().length - 2)
.replace(/\.\*\?$/, '*');
}
/**
* Coerce `val`.
*
* @param {Mixed} val
* @return {Mixed}
* @api private
*/
function coerce(val) {
if (val instanceof Error) {
return val.stack || val.message;
}
return val;
}
createDebug.enable(createDebug.load());
return createDebug;
}
module.exports = setup;
+4 -4
View File
@@ -1,10 +1,10 @@
/**
* Detect Electron renderer process, which is node, but we should
* Detect Electron renderer / nwjs process, which is node, but we should
* treat as a browser.
*/
if (typeof process === 'undefined' || process.type === 'renderer') {
module.exports = require('./browser.js');
if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) {
module.exports = require('./browser.js');
} else {
module.exports = require('./node.js');
module.exports = require('./node.js');
}
+164 -93
View File
@@ -2,16 +2,13 @@
* Module dependencies.
*/
var tty = require('tty');
var util = require('util');
const tty = require('tty');
const util = require('util');
/**
* This is the Node.js implementation of `debug()`.
*
* Expose `debug()` as the module.
*/
exports = module.exports = require('./debug');
exports.init = init;
exports.log = log;
exports.formatArgs = formatArgs;
@@ -23,21 +20,95 @@ exports.useColors = useColors;
* Colors.
*/
exports.colors = [ 6, 2, 3, 4, 5, 1 ];
exports.colors = [6, 2, 3, 4, 5, 1];
try {
var supportsColor = require('supports-color');
if (supportsColor && supportsColor.level >= 2) {
exports.colors = [
20, 21, 26, 27, 32, 33, 38, 39, 40, 41, 42, 43, 44, 45, 56, 57, 62, 63, 68,
69, 74, 75, 76, 77, 78, 79, 80, 81, 92, 93, 98, 99, 112, 113, 128, 129, 134,
135, 148, 149, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171,
172, 173, 178, 179, 184, 185, 196, 197, 198, 199, 200, 201, 202, 203, 204,
205, 206, 207, 208, 209, 214, 215, 220, 221
];
}
} catch (err) {
// swallow - we only care if `supports-color` is available; it doesn't have to be.
// Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json)
// eslint-disable-next-line import/no-extraneous-dependencies
const supportsColor = require('supports-color');
if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {
exports.colors = [
20,
21,
26,
27,
32,
33,
38,
39,
40,
41,
42,
43,
44,
45,
56,
57,
62,
63,
68,
69,
74,
75,
76,
77,
78,
79,
80,
81,
92,
93,
98,
99,
112,
113,
128,
129,
134,
135,
148,
149,
160,
161,
162,
163,
164,
165,
166,
167,
168,
169,
170,
171,
172,
173,
178,
179,
184,
185,
196,
197,
198,
199,
200,
201,
202,
203,
204,
205,
206,
207,
208,
209,
214,
215,
220,
221
];
}
} catch (error) {
// Swallow - we only care if `supports-color` is available; it doesn't have to be.
}
/**
@@ -46,24 +117,31 @@ try {
* $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js
*/
exports.inspectOpts = Object.keys(process.env).filter(function (key) {
return /^debug_/i.test(key);
}).reduce(function (obj, key) {
// camel-case
var prop = key
.substring(6)
.toLowerCase()
.replace(/_([a-z])/g, function (_, k) { return k.toUpperCase() });
exports.inspectOpts = Object.keys(process.env).filter(key => {
return /^debug_/i.test(key);
}).reduce((obj, key) => {
// Camel-case
const prop = key
.substring(6)
.toLowerCase()
.replace(/_([a-z])/g, (_, k) => {
return k.toUpperCase();
});
// coerce string value into JS value
var val = process.env[key];
if (/^(yes|on|true|enabled)$/i.test(val)) val = true;
else if (/^(no|off|false|disabled)$/i.test(val)) val = false;
else if (val === 'null') val = null;
else val = Number(val);
// Coerce string value into JS value
let val = process.env[key];
if (/^(yes|on|true|enabled)$/i.test(val)) {
val = true;
} else if (/^(no|off|false|disabled)$/i.test(val)) {
val = false;
} else if (val === 'null') {
val = null;
} else {
val = Number(val);
}
obj[prop] = val;
return obj;
obj[prop] = val;
return obj;
}, {});
/**
@@ -71,32 +149,11 @@ exports.inspectOpts = Object.keys(process.env).filter(function (key) {
*/
function useColors() {
return 'colors' in exports.inspectOpts
? Boolean(exports.inspectOpts.colors)
: tty.isatty(process.stderr.fd);
return 'colors' in exports.inspectOpts ?
Boolean(exports.inspectOpts.colors) :
tty.isatty(process.stderr.fd);
}
/**
* Map %o to `util.inspect()`, all on a single line.
*/
exports.formatters.o = function(v) {
this.inspectOpts.colors = this.useColors;
return util.inspect(v, this.inspectOpts)
.split('\n').map(function(str) {
return str.trim()
}).join(' ');
};
/**
* Map %o to `util.inspect()`, allowing multiple lines if needed.
*/
exports.formatters.O = function(v) {
this.inspectOpts.colors = this.useColors;
return util.inspect(v, this.inspectOpts);
};
/**
* Adds ANSI color escape codes if enabled.
*
@@ -104,35 +161,33 @@ exports.formatters.O = function(v) {
*/
function formatArgs(args) {
var name = this.namespace;
var useColors = this.useColors;
const {namespace: name, useColors} = this;
if (useColors) {
var c = this.color;
var colorCode = '\u001b[3' + (c < 8 ? c : '8;5;' + c);
var prefix = ' ' + colorCode + ';1m' + name + ' ' + '\u001b[0m';
if (useColors) {
const c = this.color;
const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c);
const prefix = ` ${colorCode};1m${name} \u001B[0m`;
args[0] = prefix + args[0].split('\n').join('\n' + prefix);
args.push(colorCode + 'm+' + exports.humanize(this.diff) + '\u001b[0m');
} else {
args[0] = getDate() + name + ' ' + args[0];
}
args[0] = prefix + args[0].split('\n').join('\n' + prefix);
args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\u001B[0m');
} else {
args[0] = getDate() + name + ' ' + args[0];
}
}
function getDate() {
if (exports.inspectOpts.hideDate) {
return '';
} else {
return new Date().toISOString() + ' ';
}
if (exports.inspectOpts.hideDate) {
return '';
}
return new Date().toISOString() + ' ';
}
/**
* Invokes `util.format()` with the specified arguments and writes to stderr.
*/
function log() {
return process.stderr.write(util.format.apply(util, arguments) + '\n');
function log(...args) {
return process.stderr.write(util.format(...args) + '\n');
}
/**
@@ -141,15 +196,14 @@ function log() {
* @param {String} namespaces
* @api private
*/
function save(namespaces) {
if (null == namespaces) {
// If you set a process.env field to null or undefined, it gets cast to the
// string 'null' or 'undefined'. Just delete instead.
delete process.env.DEBUG;
} else {
process.env.DEBUG = namespaces;
}
if (namespaces) {
process.env.DEBUG = namespaces;
} else {
// If you set a process.env field to null or undefined, it gets cast to the
// string 'null' or 'undefined'. Just delete instead.
delete process.env.DEBUG;
}
}
/**
@@ -160,7 +214,7 @@ function save(namespaces) {
*/
function load() {
return process.env.DEBUG;
return process.env.DEBUG;
}
/**
@@ -170,17 +224,34 @@ function load() {
* differently for a particular `debug` instance.
*/
function init (debug) {
debug.inspectOpts = {};
function init(debug) {
debug.inspectOpts = {};
var keys = Object.keys(exports.inspectOpts);
for (var i = 0; i < keys.length; i++) {
debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];
}
const keys = Object.keys(exports.inspectOpts);
for (let i = 0; i < keys.length; i++) {
debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];
}
}
module.exports = require('./common')(exports);
const {formatters} = module.exports;
/**
* Enable namespaces listed in `process.env.DEBUG` initially.
* Map %o to `util.inspect()`, all on a single line.
*/
exports.enable(load());
formatters.o = function (v) {
this.inspectOpts.colors = this.useColors;
return util.inspect(v, this.inspectOpts)
.replace(/\s*\n\s*/g, ' ');
};
/**
* Map %O to `util.inspect()`, allowing multiple lines if needed.
*/
formatters.O = function (v) {
this.inspectOpts.colors = this.useColors;
return util.inspect(v, this.inspectOpts);
};
+3 -2
View File
@@ -31,6 +31,7 @@ function log (message /*: string */) {
const NEWLINE = '\n'
const RE_INI_KEY_VAL = /^\s*([\w.-]+)\s*=\s*(.*)?\s*$/
const RE_NEWLINES = /\\n/g
const NEWLINES_MATCH = /\n|\r|\r\n/
// Parses src into an Object
function parse (src /*: string | Buffer */, options /*: ?DotenvParseOptions */) /*: DotenvParseOutput */ {
@@ -38,7 +39,7 @@ function parse (src /*: string | Buffer */, options /*: ?DotenvParseOptions */)
const obj = {}
// convert Buffers before splitting into lines and processing
src.toString().split(NEWLINE).forEach(function (line, idx) {
src.toString().split(NEWLINES_MATCH).forEach(function (line, idx) {
// matching "KEY' and 'VAL' in 'KEY=VAL'
const keyValueArr = line.match(RE_INI_KEY_VAL)
// matched?
@@ -95,7 +96,7 @@ function config (options /*: ?DotenvConfigOptions */) /*: DotenvConfigOutput */
const parsed = parse(fs.readFileSync(dotenvPath, { encoding }), { debug })
Object.keys(parsed).forEach(function (key) {
if (!process.env.hasOwnProperty(key)) {
if (!Object.prototype.hasOwnProperty.call(process.env, key)) {
process.env[key] = parsed[key]
} else if (debug) {
log(`"${key}" is already defined in \`process.env\` and will not be overwritten`)
+24 -24
View File
@@ -1,46 +1,44 @@
{
"_args": [
[
"dotenv@8.0.0",
"C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer"
]
],
"_from": "dotenv@8.0.0",
"_id": "dotenv@8.0.0",
"_from": "dotenv@8.2.0",
"_id": "dotenv@8.2.0",
"_inBundle": false,
"_integrity": "sha512-30xVGqjLjiUOArT4+M5q9sYdvuR4riM6yK9wMcas9Vbp6zZa+ocC9dp6QoftuhTPhFAiLK/0C5Ni2nou/Bk8lg==",
"_integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
"_location": "/dotenv",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "dotenv@8.0.0",
"raw": "dotenv@8.2.0",
"name": "dotenv",
"escapedName": "dotenv",
"rawSpec": "8.0.0",
"rawSpec": "8.2.0",
"saveSpec": null,
"fetchSpec": "8.0.0"
"fetchSpec": "8.2.0"
},
"_requiredBy": [
"/",
"/@superalgos/exchange-gateway"
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.0.0.tgz",
"_spec": "8.0.0",
"_resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
"_shasum": "97e619259ada750eea3e4ea3e26bceea5424b16a",
"_spec": "dotenv@8.2.0",
"_where": "C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer",
"bugs": {
"url": "https://github.com/motdotla/dotenv/issues"
},
"bundleDependencies": false,
"dependencies": {},
"deprecated": false,
"description": "Loads environment variables from .env file",
"devDependencies": {
"decache": "^4.5.1",
"flow-bin": "^0.98.0",
"sinon": "^7.3.2",
"standard": "^12.0.1",
"standard-markdown": "^5.0.1",
"standard-version": "^5.0.2",
"tap": "^13.1.2"
"dtslint": "^0.9.8",
"flow-bin": "^0.109.0",
"sinon": "^7.5.0",
"standard": "^13.1.0",
"standard-markdown": "^5.1.0",
"standard-version": "^7.0.0",
"tap": "^14.7.0"
},
"engines": {
"node": ">=8"
@@ -63,11 +61,12 @@
"url": "git://github.com/motdotla/dotenv.git"
},
"scripts": {
"dtslint": "dtslint types",
"flow": "flow",
"lint": "standard",
"postlint": "standard-markdown",
"prerelease": "npm test",
"pretest": "npm run lint",
"pretest": "npm run lint && npm run dtslint",
"release": "standard-version",
"test": "tap tests/*.js --100"
},
@@ -76,5 +75,6 @@
"flow-typed/"
]
},
"version": "8.0.0"
"types": "types",
"version": "8.2.0"
}
+15
View File
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": ["es6"],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noEmit": true,
"baseUrl": ".",
"paths": {
"dotenv": ["."]
}
}
}
+6
View File
@@ -0,0 +1,6 @@
{
"extends": "dtslint/dtslint.json",
"rules": {
"strict-export-declare-modifiers": false
}
}
+2
View File
@@ -0,0 +1,2 @@
var argv = require('../')(process.argv.slice(2));
console.dir(argv);
+236
View File
@@ -0,0 +1,236 @@
module.exports = function (args, opts) {
if (!opts) opts = {};
var flags = { bools : {}, strings : {}, unknownFn: null };
if (typeof opts['unknown'] === 'function') {
flags.unknownFn = opts['unknown'];
}
if (typeof opts['boolean'] === 'boolean' && opts['boolean']) {
flags.allBools = true;
} else {
[].concat(opts['boolean']).filter(Boolean).forEach(function (key) {
flags.bools[key] = true;
});
}
var aliases = {};
Object.keys(opts.alias || {}).forEach(function (key) {
aliases[key] = [].concat(opts.alias[key]);
aliases[key].forEach(function (x) {
aliases[x] = [key].concat(aliases[key].filter(function (y) {
return x !== y;
}));
});
});
[].concat(opts.string).filter(Boolean).forEach(function (key) {
flags.strings[key] = true;
if (aliases[key]) {
flags.strings[aliases[key]] = true;
}
});
var defaults = opts['default'] || {};
var argv = { _ : [] };
Object.keys(flags.bools).forEach(function (key) {
setArg(key, defaults[key] === undefined ? false : defaults[key]);
});
var notFlags = [];
if (args.indexOf('--') !== -1) {
notFlags = args.slice(args.indexOf('--')+1);
args = args.slice(0, args.indexOf('--'));
}
function argDefined(key, arg) {
return (flags.allBools && /^--[^=]+$/.test(arg)) ||
flags.strings[key] || flags.bools[key] || aliases[key];
}
function setArg (key, val, arg) {
if (arg && flags.unknownFn && !argDefined(key, arg)) {
if (flags.unknownFn(arg) === false) return;
}
var value = !flags.strings[key] && isNumber(val)
? Number(val) : val
;
setKey(argv, key.split('.'), value);
(aliases[key] || []).forEach(function (x) {
setKey(argv, x.split('.'), value);
});
}
function setKey (obj, keys, value) {
var o = obj;
keys.slice(0,-1).forEach(function (key) {
if (o[key] === undefined) o[key] = {};
o = o[key];
});
var key = keys[keys.length - 1];
if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') {
o[key] = value;
}
else if (Array.isArray(o[key])) {
o[key].push(value);
}
else {
o[key] = [ o[key], value ];
}
}
function aliasIsBoolean(key) {
return aliases[key].some(function (x) {
return flags.bools[x];
});
}
for (var i = 0; i < args.length; i++) {
var arg = args[i];
if (/^--.+=/.test(arg)) {
// Using [\s\S] instead of . because js doesn't support the
// 'dotall' regex modifier. See:
// http://stackoverflow.com/a/1068308/13216
var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
var key = m[1];
var value = m[2];
if (flags.bools[key]) {
value = value !== 'false';
}
setArg(key, value, arg);
}
else if (/^--no-.+/.test(arg)) {
var key = arg.match(/^--no-(.+)/)[1];
setArg(key, false, arg);
}
else if (/^--.+/.test(arg)) {
var key = arg.match(/^--(.+)/)[1];
var next = args[i + 1];
if (next !== undefined && !/^-/.test(next)
&& !flags.bools[key]
&& !flags.allBools
&& (aliases[key] ? !aliasIsBoolean(key) : true)) {
setArg(key, next, arg);
i++;
}
else if (/^(true|false)$/.test(next)) {
setArg(key, next === 'true', arg);
i++;
}
else {
setArg(key, flags.strings[key] ? '' : true, arg);
}
}
else if (/^-[^-]+/.test(arg)) {
var letters = arg.slice(1,-1).split('');
var broken = false;
for (var j = 0; j < letters.length; j++) {
var next = arg.slice(j+2);
if (next === '-') {
setArg(letters[j], next, arg)
continue;
}
if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) {
setArg(letters[j], next.split('=')[1], arg);
broken = true;
break;
}
if (/[A-Za-z]/.test(letters[j])
&& /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
setArg(letters[j], next, arg);
broken = true;
break;
}
if (letters[j+1] && letters[j+1].match(/\W/)) {
setArg(letters[j], arg.slice(j+2), arg);
broken = true;
break;
}
else {
setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg);
}
}
var key = arg.slice(-1)[0];
if (!broken && key !== '-') {
if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1])
&& !flags.bools[key]
&& (aliases[key] ? !aliasIsBoolean(key) : true)) {
setArg(key, args[i+1], arg);
i++;
}
else if (args[i+1] && /true|false/.test(args[i+1])) {
setArg(key, args[i+1] === 'true', arg);
i++;
}
else {
setArg(key, flags.strings[key] ? '' : true, arg);
}
}
}
else {
if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
argv._.push(
flags.strings['_'] || !isNumber(arg) ? arg : Number(arg)
);
}
if (opts.stopEarly) {
argv._.push.apply(argv._, args.slice(i + 1));
break;
}
}
}
Object.keys(defaults).forEach(function (key) {
if (!hasKey(argv, key.split('.'))) {
setKey(argv, key.split('.'), defaults[key]);
(aliases[key] || []).forEach(function (x) {
setKey(argv, x.split('.'), defaults[key]);
});
}
});
if (opts['--']) {
argv['--'] = new Array();
notFlags.forEach(function(key) {
argv['--'].push(key);
});
}
else {
notFlags.forEach(function(key) {
argv._.push(key);
});
}
return argv;
};
function hasKey (obj, keys) {
var o = obj;
keys.slice(0,-1).forEach(function (key) {
o = (o[key] || {});
});
var key = keys[keys.length - 1];
return key in o;
}
function isNumber (x) {
if (typeof x === 'number') return true;
if (/^0x[0-9a-f]+$/i.test(x)) return true;
return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x);
}
+73
View File
@@ -0,0 +1,73 @@
{
"_from": "minimist@^1.2.0",
"_id": "minimist@1.2.0",
"_inBundle": false,
"_integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"_location": "/minimist",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "minimist@^1.2.0",
"name": "minimist",
"escapedName": "minimist",
"rawSpec": "^1.2.0",
"saveSpec": null,
"fetchSpec": "^1.2.0"
},
"_requiredBy": [
"/telegraf"
],
"_resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"_shasum": "a35008b20f41383eec1fb914f4cd5df79a264284",
"_spec": "minimist@^1.2.0",
"_where": "C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer\\node_modules\\telegraf",
"author": {
"name": "James Halliday",
"email": "mail@substack.net",
"url": "http://substack.net"
},
"bugs": {
"url": "https://github.com/substack/minimist/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "parse argument options",
"devDependencies": {
"covert": "^1.0.0",
"tap": "~0.4.0",
"tape": "^3.5.0"
},
"homepage": "https://github.com/substack/minimist",
"keywords": [
"argv",
"getopt",
"parser",
"optimist"
],
"license": "MIT",
"main": "index.js",
"name": "minimist",
"repository": {
"type": "git",
"url": "git://github.com/substack/minimist.git"
},
"scripts": {
"coverage": "covert test/*.js",
"test": "tap test/*.js"
},
"testling": {
"files": "test/*.js",
"browsers": [
"ie/6..latest",
"ff/5",
"firefox/latest",
"chrome/10",
"chrome/latest",
"safari/5.1",
"safari/latest",
"opera/12"
]
},
"version": "1.2.0"
}
+32
View File
@@ -0,0 +1,32 @@
var parse = require('../');
var test = require('tape');
test('flag boolean true (default all --args to boolean)', function (t) {
var argv = parse(['moo', '--honk', 'cow'], {
boolean: true
});
t.deepEqual(argv, {
honk: true,
_: ['moo', 'cow']
});
t.deepEqual(typeof argv.honk, 'boolean');
t.end();
});
test('flag boolean true only affects double hyphen arguments without equals signs', function (t) {
var argv = parse(['moo', '--honk', 'cow', '-p', '55', '--tacos=good'], {
boolean: true
});
t.deepEqual(argv, {
honk: true,
tacos: 'good',
p: 55,
_: ['moo', 'cow']
});
t.deepEqual(typeof argv.honk, 'boolean');
t.end();
});
+166
View File
@@ -0,0 +1,166 @@
var parse = require('../');
var test = require('tape');
test('flag boolean default false', function (t) {
var argv = parse(['moo'], {
boolean: ['t', 'verbose'],
default: { verbose: false, t: false }
});
t.deepEqual(argv, {
verbose: false,
t: false,
_: ['moo']
});
t.deepEqual(typeof argv.verbose, 'boolean');
t.deepEqual(typeof argv.t, 'boolean');
t.end();
});
test('boolean groups', function (t) {
var argv = parse([ '-x', '-z', 'one', 'two', 'three' ], {
boolean: ['x','y','z']
});
t.deepEqual(argv, {
x : true,
y : false,
z : true,
_ : [ 'one', 'two', 'three' ]
});
t.deepEqual(typeof argv.x, 'boolean');
t.deepEqual(typeof argv.y, 'boolean');
t.deepEqual(typeof argv.z, 'boolean');
t.end();
});
test('boolean and alias with chainable api', function (t) {
var aliased = [ '-h', 'derp' ];
var regular = [ '--herp', 'derp' ];
var opts = {
herp: { alias: 'h', boolean: true }
};
var aliasedArgv = parse(aliased, {
boolean: 'herp',
alias: { h: 'herp' }
});
var propertyArgv = parse(regular, {
boolean: 'herp',
alias: { h: 'herp' }
});
var expected = {
herp: true,
h: true,
'_': [ 'derp' ]
};
t.same(aliasedArgv, expected);
t.same(propertyArgv, expected);
t.end();
});
test('boolean and alias with options hash', function (t) {
var aliased = [ '-h', 'derp' ];
var regular = [ '--herp', 'derp' ];
var opts = {
alias: { 'h': 'herp' },
boolean: 'herp'
};
var aliasedArgv = parse(aliased, opts);
var propertyArgv = parse(regular, opts);
var expected = {
herp: true,
h: true,
'_': [ 'derp' ]
};
t.same(aliasedArgv, expected);
t.same(propertyArgv, expected);
t.end();
});
test('boolean and alias array with options hash', function (t) {
var aliased = [ '-h', 'derp' ];
var regular = [ '--herp', 'derp' ];
var alt = [ '--harp', 'derp' ];
var opts = {
alias: { 'h': ['herp', 'harp'] },
boolean: 'h'
};
var aliasedArgv = parse(aliased, opts);
var propertyArgv = parse(regular, opts);
var altPropertyArgv = parse(alt, opts);
var expected = {
harp: true,
herp: true,
h: true,
'_': [ 'derp' ]
};
t.same(aliasedArgv, expected);
t.same(propertyArgv, expected);
t.same(altPropertyArgv, expected);
t.end();
});
test('boolean and alias using explicit true', function (t) {
var aliased = [ '-h', 'true' ];
var regular = [ '--herp', 'true' ];
var opts = {
alias: { h: 'herp' },
boolean: 'h'
};
var aliasedArgv = parse(aliased, opts);
var propertyArgv = parse(regular, opts);
var expected = {
herp: true,
h: true,
'_': [ ]
};
t.same(aliasedArgv, expected);
t.same(propertyArgv, expected);
t.end();
});
// regression, see https://github.com/substack/node-optimist/issues/71
test('boolean and --x=true', function(t) {
var parsed = parse(['--boool', '--other=true'], {
boolean: 'boool'
});
t.same(parsed.boool, true);
t.same(parsed.other, 'true');
parsed = parse(['--boool', '--other=false'], {
boolean: 'boool'
});
t.same(parsed.boool, true);
t.same(parsed.other, 'false');
t.end();
});
test('boolean --boool=true', function (t) {
var parsed = parse(['--boool=true'], {
default: {
boool: false
},
boolean: ['boool']
});
t.same(parsed.boool, true);
t.end();
});
test('boolean --boool=false', function (t) {
var parsed = parse(['--boool=false'], {
default: {
boool: true
},
boolean: ['boool']
});
t.same(parsed.boool, false);
t.end();
});
+31
View File
@@ -0,0 +1,31 @@
var parse = require('../');
var test = require('tape');
test('-', function (t) {
t.plan(5);
t.deepEqual(parse([ '-n', '-' ]), { n: '-', _: [] });
t.deepEqual(parse([ '-' ]), { _: [ '-' ] });
t.deepEqual(parse([ '-f-' ]), { f: '-', _: [] });
t.deepEqual(
parse([ '-b', '-' ], { boolean: 'b' }),
{ b: true, _: [ '-' ] }
);
t.deepEqual(
parse([ '-s', '-' ], { string: 's' }),
{ s: '-', _: [] }
);
});
test('-a -- b', function (t) {
t.plan(3);
t.deepEqual(parse([ '-a', '--', 'b' ]), { a: true, _: [ 'b' ] });
t.deepEqual(parse([ '--a', '--', 'b' ]), { a: true, _: [ 'b' ] });
t.deepEqual(parse([ '--a', '--', 'b' ]), { a: true, _: [ 'b' ] });
});
test('move arguments after the -- into their own `--` array', function(t) {
t.plan(1);
t.deepEqual(
parse([ '--name', 'John', 'before', '--', 'after' ], { '--': true }),
{ name: 'John', _: [ 'before' ], '--': [ 'after' ] });
});
+35
View File
@@ -0,0 +1,35 @@
var test = require('tape');
var parse = require('../');
test('boolean default true', function (t) {
var argv = parse([], {
boolean: 'sometrue',
default: { sometrue: true }
});
t.equal(argv.sometrue, true);
t.end();
});
test('boolean default false', function (t) {
var argv = parse([], {
boolean: 'somefalse',
default: { somefalse: false }
});
t.equal(argv.somefalse, false);
t.end();
});
test('boolean default to null', function (t) {
var argv = parse([], {
boolean: 'maybe',
default: { maybe: null }
});
t.equal(argv.maybe, null);
var argv = parse(['--maybe'], {
boolean: 'maybe',
default: { maybe: null }
});
t.equal(argv.maybe, true);
t.end();
})
+22
View File
@@ -0,0 +1,22 @@
var parse = require('../');
var test = require('tape');
test('dotted alias', function (t) {
var argv = parse(['--a.b', '22'], {default: {'a.b': 11}, alias: {'a.b': 'aa.bb'}});
t.equal(argv.a.b, 22);
t.equal(argv.aa.bb, 22);
t.end();
});
test('dotted default', function (t) {
var argv = parse('', {default: {'a.b': 11}, alias: {'a.b': 'aa.bb'}});
t.equal(argv.a.b, 11);
t.equal(argv.aa.bb, 11);
t.end();
});
test('dotted default with no alias', function (t) {
var argv = parse('', {default: {'a.b': 11}});
t.equal(argv.a.b, 11);
t.end();
});
+16
View File
@@ -0,0 +1,16 @@
var parse = require('../');
var test = require('tape');
test('short -k=v' , function (t) {
t.plan(1);
var argv = parse([ '-b=123' ]);
t.deepEqual(argv, { b: 123, _: [] });
});
test('multi short -k=v' , function (t) {
t.plan(1);
var argv = parse([ '-a=whatever', '-b=robots' ]);
t.deepEqual(argv, { a: 'whatever', b: 'robots', _: [] });
});
+31
View File
@@ -0,0 +1,31 @@
var test = require('tape');
var parse = require('../');
test('long opts', function (t) {
t.deepEqual(
parse([ '--bool' ]),
{ bool : true, _ : [] },
'long boolean'
);
t.deepEqual(
parse([ '--pow', 'xixxle' ]),
{ pow : 'xixxle', _ : [] },
'long capture sp'
);
t.deepEqual(
parse([ '--pow=xixxle' ]),
{ pow : 'xixxle', _ : [] },
'long capture eq'
);
t.deepEqual(
parse([ '--host', 'localhost', '--port', '555' ]),
{ host : 'localhost', port : 555, _ : [] },
'long captures sp'
);
t.deepEqual(
parse([ '--host=localhost', '--port=555' ]),
{ host : 'localhost', port : 555, _ : [] },
'long captures eq'
);
t.end();
});
+36
View File
@@ -0,0 +1,36 @@
var parse = require('../');
var test = require('tape');
test('nums', function (t) {
var argv = parse([
'-x', '1234',
'-y', '5.67',
'-z', '1e7',
'-w', '10f',
'--hex', '0xdeadbeef',
'789'
]);
t.deepEqual(argv, {
x : 1234,
y : 5.67,
z : 1e7,
w : '10f',
hex : 0xdeadbeef,
_ : [ 789 ]
});
t.deepEqual(typeof argv.x, 'number');
t.deepEqual(typeof argv.y, 'number');
t.deepEqual(typeof argv.z, 'number');
t.deepEqual(typeof argv.w, 'string');
t.deepEqual(typeof argv.hex, 'number');
t.deepEqual(typeof argv._[0], 'number');
t.end();
});
test('already a number', function (t) {
var argv = parse([ '-x', 1234, 789 ]);
t.deepEqual(argv, { x : 1234, _ : [ 789 ] });
t.deepEqual(typeof argv.x, 'number');
t.deepEqual(typeof argv._[0], 'number');
t.end();
});
+197
View File
@@ -0,0 +1,197 @@
var parse = require('../');
var test = require('tape');
test('parse args', function (t) {
t.deepEqual(
parse([ '--no-moo' ]),
{ moo : false, _ : [] },
'no'
);
t.deepEqual(
parse([ '-v', 'a', '-v', 'b', '-v', 'c' ]),
{ v : ['a','b','c'], _ : [] },
'multi'
);
t.end();
});
test('comprehensive', function (t) {
t.deepEqual(
parse([
'--name=meowmers', 'bare', '-cats', 'woo',
'-h', 'awesome', '--multi=quux',
'--key', 'value',
'-b', '--bool', '--no-meep', '--multi=baz',
'--', '--not-a-flag', 'eek'
]),
{
c : true,
a : true,
t : true,
s : 'woo',
h : 'awesome',
b : true,
bool : true,
key : 'value',
multi : [ 'quux', 'baz' ],
meep : false,
name : 'meowmers',
_ : [ 'bare', '--not-a-flag', 'eek' ]
}
);
t.end();
});
test('flag boolean', function (t) {
var argv = parse([ '-t', 'moo' ], { boolean: 't' });
t.deepEqual(argv, { t : true, _ : [ 'moo' ] });
t.deepEqual(typeof argv.t, 'boolean');
t.end();
});
test('flag boolean value', function (t) {
var argv = parse(['--verbose', 'false', 'moo', '-t', 'true'], {
boolean: [ 't', 'verbose' ],
default: { verbose: true }
});
t.deepEqual(argv, {
verbose: false,
t: true,
_: ['moo']
});
t.deepEqual(typeof argv.verbose, 'boolean');
t.deepEqual(typeof argv.t, 'boolean');
t.end();
});
test('newlines in params' , function (t) {
var args = parse([ '-s', "X\nX" ])
t.deepEqual(args, { _ : [], s : "X\nX" });
// reproduce in bash:
// VALUE="new
// line"
// node program.js --s="$VALUE"
args = parse([ "--s=X\nX" ])
t.deepEqual(args, { _ : [], s : "X\nX" });
t.end();
});
test('strings' , function (t) {
var s = parse([ '-s', '0001234' ], { string: 's' }).s;
t.equal(s, '0001234');
t.equal(typeof s, 'string');
var x = parse([ '-x', '56' ], { string: 'x' }).x;
t.equal(x, '56');
t.equal(typeof x, 'string');
t.end();
});
test('stringArgs', function (t) {
var s = parse([ ' ', ' ' ], { string: '_' })._;
t.same(s.length, 2);
t.same(typeof s[0], 'string');
t.same(s[0], ' ');
t.same(typeof s[1], 'string');
t.same(s[1], ' ');
t.end();
});
test('empty strings', function(t) {
var s = parse([ '-s' ], { string: 's' }).s;
t.equal(s, '');
t.equal(typeof s, 'string');
var str = parse([ '--str' ], { string: 'str' }).str;
t.equal(str, '');
t.equal(typeof str, 'string');
var letters = parse([ '-art' ], {
string: [ 'a', 't' ]
});
t.equal(letters.a, '');
t.equal(letters.r, true);
t.equal(letters.t, '');
t.end();
});
test('string and alias', function(t) {
var x = parse([ '--str', '000123' ], {
string: 's',
alias: { s: 'str' }
});
t.equal(x.str, '000123');
t.equal(typeof x.str, 'string');
t.equal(x.s, '000123');
t.equal(typeof x.s, 'string');
var y = parse([ '-s', '000123' ], {
string: 'str',
alias: { str: 's' }
});
t.equal(y.str, '000123');
t.equal(typeof y.str, 'string');
t.equal(y.s, '000123');
t.equal(typeof y.s, 'string');
t.end();
});
test('slashBreak', function (t) {
t.same(
parse([ '-I/foo/bar/baz' ]),
{ I : '/foo/bar/baz', _ : [] }
);
t.same(
parse([ '-xyz/foo/bar/baz' ]),
{ x : true, y : true, z : '/foo/bar/baz', _ : [] }
);
t.end();
});
test('alias', function (t) {
var argv = parse([ '-f', '11', '--zoom', '55' ], {
alias: { z: 'zoom' }
});
t.equal(argv.zoom, 55);
t.equal(argv.z, argv.zoom);
t.equal(argv.f, 11);
t.end();
});
test('multiAlias', function (t) {
var argv = parse([ '-f', '11', '--zoom', '55' ], {
alias: { z: [ 'zm', 'zoom' ] }
});
t.equal(argv.zoom, 55);
t.equal(argv.z, argv.zoom);
t.equal(argv.z, argv.zm);
t.equal(argv.f, 11);
t.end();
});
test('nested dotted objects', function (t) {
var argv = parse([
'--foo.bar', '3', '--foo.baz', '4',
'--foo.quux.quibble', '5', '--foo.quux.o_O',
'--beep.boop'
]);
t.same(argv.foo, {
bar : 3,
baz : 4,
quux : {
quibble : 5,
o_O : true
}
});
t.same(argv.beep, { boop : true });
t.end();
});
+9
View File
@@ -0,0 +1,9 @@
var parse = require('../');
var test = require('tape');
test('parse with modifier functions' , function (t) {
t.plan(1);
var argv = parse([ '-b', '123' ], { boolean: 'b' });
t.deepEqual(argv, { b: true, _: [123] });
});
+67
View File
@@ -0,0 +1,67 @@
var parse = require('../');
var test = require('tape');
test('numeric short args', function (t) {
t.plan(2);
t.deepEqual(parse([ '-n123' ]), { n: 123, _: [] });
t.deepEqual(
parse([ '-123', '456' ]),
{ 1: true, 2: true, 3: 456, _: [] }
);
});
test('short', function (t) {
t.deepEqual(
parse([ '-b' ]),
{ b : true, _ : [] },
'short boolean'
);
t.deepEqual(
parse([ 'foo', 'bar', 'baz' ]),
{ _ : [ 'foo', 'bar', 'baz' ] },
'bare'
);
t.deepEqual(
parse([ '-cats' ]),
{ c : true, a : true, t : true, s : true, _ : [] },
'group'
);
t.deepEqual(
parse([ '-cats', 'meow' ]),
{ c : true, a : true, t : true, s : 'meow', _ : [] },
'short group next'
);
t.deepEqual(
parse([ '-h', 'localhost' ]),
{ h : 'localhost', _ : [] },
'short capture'
);
t.deepEqual(
parse([ '-h', 'localhost', '-p', '555' ]),
{ h : 'localhost', p : 555, _ : [] },
'short captures'
);
t.end();
});
test('mixed short bool and capture', function (t) {
t.same(
parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]),
{
f : true, p : 555, h : 'localhost',
_ : [ 'script.js' ]
}
);
t.end();
});
test('short and long', function (t) {
t.deepEqual(
parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]),
{
f : true, p : 555, h : 'localhost',
_ : [ 'script.js' ]
}
);
t.end();
});
+15
View File
@@ -0,0 +1,15 @@
var parse = require('../');
var test = require('tape');
test('stops parsing on the first non-option when stopEarly is set', function (t) {
var argv = parse(['--aaa', 'bbb', 'ccc', '--ddd'], {
stopEarly: true
});
t.deepEqual(argv, {
aaa: 'bbb',
_: ['ccc', '--ddd']
});
t.end();
});
+102
View File
@@ -0,0 +1,102 @@
var parse = require('../');
var test = require('tape');
test('boolean and alias is not unknown', function (t) {
var unknown = [];
function unknownFn(arg) {
unknown.push(arg);
return false;
}
var aliased = [ '-h', 'true', '--derp', 'true' ];
var regular = [ '--herp', 'true', '-d', 'true' ];
var opts = {
alias: { h: 'herp' },
boolean: 'h',
unknown: unknownFn
};
var aliasedArgv = parse(aliased, opts);
var propertyArgv = parse(regular, opts);
t.same(unknown, ['--derp', '-d']);
t.end();
});
test('flag boolean true any double hyphen argument is not unknown', function (t) {
var unknown = [];
function unknownFn(arg) {
unknown.push(arg);
return false;
}
var argv = parse(['--honk', '--tacos=good', 'cow', '-p', '55'], {
boolean: true,
unknown: unknownFn
});
t.same(unknown, ['--tacos=good', 'cow', '-p']);
t.same(argv, {
honk: true,
_: []
});
t.end();
});
test('string and alias is not unknown', function (t) {
var unknown = [];
function unknownFn(arg) {
unknown.push(arg);
return false;
}
var aliased = [ '-h', 'hello', '--derp', 'goodbye' ];
var regular = [ '--herp', 'hello', '-d', 'moon' ];
var opts = {
alias: { h: 'herp' },
string: 'h',
unknown: unknownFn
};
var aliasedArgv = parse(aliased, opts);
var propertyArgv = parse(regular, opts);
t.same(unknown, ['--derp', '-d']);
t.end();
});
test('default and alias is not unknown', function (t) {
var unknown = [];
function unknownFn(arg) {
unknown.push(arg);
return false;
}
var aliased = [ '-h', 'hello' ];
var regular = [ '--herp', 'hello' ];
var opts = {
default: { 'h': 'bar' },
alias: { 'h': 'herp' },
unknown: unknownFn
};
var aliasedArgv = parse(aliased, opts);
var propertyArgv = parse(regular, opts);
t.same(unknown, []);
t.end();
unknownFn(); // exercise fn for 100% coverage
});
test('value following -- is not unknown', function (t) {
var unknown = [];
function unknownFn(arg) {
unknown.push(arg);
return false;
}
var aliased = [ '--bad', '--', 'good', 'arg' ];
var opts = {
'--': true,
unknown: unknownFn
};
var argv = parse(aliased, opts);
t.same(unknown, ['--bad']);
t.same(argv, {
'--': ['good', 'arg'],
'_': []
})
t.end();
});
+8
View File
@@ -0,0 +1,8 @@
var parse = require('../');
var test = require('tape');
test('whitespace should be whitespace' , function (t) {
t.plan(1);
var x = parse([ '-x', '\t' ]).x;
t.equal(x, '\t');
});
+224
View File
@@ -0,0 +1,224 @@
'use strict'
var BuiltinModule = require('module')
// Guard against poorly mocked module constructors
var Module = module.constructor.length > 1
? module.constructor
: BuiltinModule
var nodePath = require('path')
var modulePaths = []
var moduleAliases = {}
var moduleAliasNames = []
var oldNodeModulePaths = Module._nodeModulePaths
Module._nodeModulePaths = function (from) {
var paths = oldNodeModulePaths.call(this, from)
// Only include the module path for top-level modules
// that were not installed:
if (from.indexOf('node_modules') === -1) {
paths = modulePaths.concat(paths)
}
return paths
}
var oldResolveFilename = Module._resolveFilename
Module._resolveFilename = function (request, parentModule, isMain, options) {
for (var i = moduleAliasNames.length; i-- > 0;) {
var alias = moduleAliasNames[i]
if (isPathMatchesAlias(request, alias)) {
var aliasTarget = moduleAliases[alias]
// Custom function handler
if (typeof moduleAliases[alias] === 'function') {
var fromPath = parentModule.filename
aliasTarget = moduleAliases[alias](fromPath, request, alias)
if (!aliasTarget || typeof aliasTarget !== 'string') {
throw new Error('[module-alias] Expecting custom handler function to return path.')
}
}
request = nodePath.join(aliasTarget, request.substr(alias.length))
// Only use the first match
break
}
}
return oldResolveFilename.call(this, request, parentModule, isMain, options)
}
function isPathMatchesAlias (path, alias) {
// Matching /^alias(\/|$)/
if (path.indexOf(alias) === 0) {
if (path.length === alias.length) return true
if (path[alias.length] === '/') return true
}
return false
}
function addPathHelper (path, targetArray) {
path = nodePath.normalize(path)
if (targetArray && targetArray.indexOf(path) === -1) {
targetArray.unshift(path)
}
}
function removePathHelper (path, targetArray) {
if (targetArray) {
var index = targetArray.indexOf(path)
if (index !== -1) {
targetArray.splice(index, 1)
}
}
}
function addPath (path) {
var parent
path = nodePath.normalize(path)
if (modulePaths.indexOf(path) === -1) {
modulePaths.push(path)
// Enable the search path for the current top-level module
var mainModule = getMainModule()
if (mainModule) {
addPathHelper(path, mainModule.paths)
}
parent = module.parent
// Also modify the paths of the module that was used to load the
// app-module-paths module and all of it's parents
while (parent && parent !== mainModule) {
addPathHelper(path, parent.paths)
parent = parent.parent
}
}
}
function addAliases (aliases) {
for (var alias in aliases) {
addAlias(alias, aliases[alias])
}
}
function addAlias (alias, target) {
moduleAliases[alias] = target
// Cost of sorting is lower here than during resolution
moduleAliasNames = Object.keys(moduleAliases)
moduleAliasNames.sort()
}
/**
* Reset any changes maded (resets all registered aliases
* and custom module directories)
* The function is undocumented and for testing purposes only
*/
function reset () {
var mainModule = getMainModule()
// Reset all changes in paths caused by addPath function
modulePaths.forEach(function (path) {
if (mainModule) {
removePathHelper(path, mainModule.paths)
}
// Delete from require.cache if the module has been required before.
// This is required for node >= 11
Object.getOwnPropertyNames(require.cache).forEach(function (name) {
if (name.indexOf(path) !== -1) {
delete require.cache[name]
}
})
var parent = module.parent
while (parent && parent !== mainModule) {
removePathHelper(path, parent.paths)
parent = parent.parent
}
})
modulePaths = []
moduleAliases = {}
moduleAliasNames = []
}
/**
* Import aliases from package.json
* @param {object} options
*/
function init (options) {
if (typeof options === 'string') {
options = { base: options }
}
options = options || {}
var candidatePackagePaths
if (options.base) {
candidatePackagePaths = [nodePath.resolve(options.base.replace(/\/package\.json$/, ''))]
} else {
// There is probably 99% chance that the project root directory in located
// above the node_modules directory,
// Or that package.json is in the node process' current working directory (when
// running a package manager script, e.g. `yarn start` / `npm run start`)
candidatePackagePaths = [nodePath.join(__dirname, '../..'), process.cwd()]
}
var npmPackage
var base
for (var i in candidatePackagePaths) {
try {
base = candidatePackagePaths[i]
npmPackage = require(nodePath.join(base, 'package.json'))
break
} catch (e) {
// noop
}
}
if (typeof npmPackage !== 'object') {
var pathString = candidatePackagePaths.join(',\n')
throw new Error('Unable to find package.json in any of:\n[' + pathString + ']')
}
//
// Import aliases
//
var aliases = npmPackage._moduleAliases || {}
for (var alias in aliases) {
if (aliases[alias][0] !== '/') {
aliases[alias] = nodePath.join(base, aliases[alias])
}
}
addAliases(aliases)
//
// Register custom module directories (like node_modules)
//
if (npmPackage._moduleDirectories instanceof Array) {
npmPackage._moduleDirectories.forEach(function (dir) {
if (dir === 'node_modules') return
var modulePath = nodePath.join(base, dir)
addPath(modulePath)
})
}
}
function getMainModule () {
return require.main._simulateRepl ? undefined : require.main
}
module.exports = init
module.exports.addPath = addPath
module.exports.addAlias = addAlias
module.exports.addAliases = addAliases
module.exports.isPathMatchesAlias = isPathMatchesAlias
module.exports.reset = reset
+76
View File
@@ -0,0 +1,76 @@
{
"_from": "module-alias@^2.2.2",
"_id": "module-alias@2.2.2",
"_inBundle": false,
"_integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==",
"_location": "/module-alias",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "module-alias@^2.2.2",
"name": "module-alias",
"escapedName": "module-alias",
"rawSpec": "^2.2.2",
"saveSpec": null,
"fetchSpec": "^2.2.2"
},
"_requiredBy": [
"/telegraf"
],
"_resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz",
"_shasum": "151cdcecc24e25739ff0aa6e51e1c5716974c0e0",
"_spec": "module-alias@^2.2.2",
"_where": "C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer\\node_modules\\telegraf",
"author": {
"name": "Nick Gavrilov",
"email": "artnikpro@gmail.com"
},
"bugs": {
"url": "https://github.com/ilearnio/module-alias/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Create aliases of directories and register custom module paths",
"devDependencies": {
"chai": "^3.5.0",
"hello-world-classic": "github:ilearnio/hello-world-classic",
"husky": "^3.0.2",
"mocha": "^2.4.5",
"semver": "^6.1.1",
"standard": "^12.0.1"
},
"files": [
"index.js",
"register.js",
"README.md",
"LICENSE"
],
"homepage": "https://github.com/ilearnio/module-alias",
"husky": {
"hooks": {
"pre-push": "npm run test"
}
},
"keywords": [
"extend",
"modules",
"node",
"path",
"resolve"
],
"license": "MIT",
"main": "index.js",
"name": "module-alias",
"repository": {
"type": "git",
"url": "git+https://github.com/ilearnio/module-alias.git"
},
"scripts": {
"lint": "standard",
"test": "npm run lint && npm run testonly",
"testonly": "NODE_ENV=test mocha test/specs.js",
"testonly-watch": "NODE_ENV=test mocha -w test/specs.js"
},
"version": "2.2.2"
}
+1
View File
@@ -0,0 +1 @@
require('.')()
+29 -19
View File
@@ -6,6 +6,7 @@ var s = 1000;
var m = s * 60;
var h = m * 60;
var d = h * 24;
var w = d * 7;
var y = d * 365.25;
/**
@@ -27,7 +28,7 @@ module.exports = function(val, options) {
var type = typeof val;
if (type === 'string' && val.length > 0) {
return parse(val);
} else if (type === 'number' && isNaN(val) === false) {
} else if (type === 'number' && isFinite(val)) {
return options.long ? fmtLong(val) : fmtShort(val);
}
throw new Error(
@@ -49,7 +50,7 @@ function parse(str) {
if (str.length > 100) {
return;
}
var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(
var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
str
);
if (!match) {
@@ -64,6 +65,10 @@ function parse(str) {
case 'yr':
case 'y':
return n * y;
case 'weeks':
case 'week':
case 'w':
return n * w;
case 'days':
case 'day':
case 'd':
@@ -106,16 +111,17 @@ function parse(str) {
*/
function fmtShort(ms) {
if (ms >= d) {
var msAbs = Math.abs(ms);
if (msAbs >= d) {
return Math.round(ms / d) + 'd';
}
if (ms >= h) {
if (msAbs >= h) {
return Math.round(ms / h) + 'h';
}
if (ms >= m) {
if (msAbs >= m) {
return Math.round(ms / m) + 'm';
}
if (ms >= s) {
if (msAbs >= s) {
return Math.round(ms / s) + 's';
}
return ms + 'ms';
@@ -130,23 +136,27 @@ function fmtShort(ms) {
*/
function fmtLong(ms) {
return plural(ms, d, 'day') ||
plural(ms, h, 'hour') ||
plural(ms, m, 'minute') ||
plural(ms, s, 'second') ||
ms + ' ms';
var msAbs = Math.abs(ms);
if (msAbs >= d) {
return plural(ms, msAbs, d, 'day');
}
if (msAbs >= h) {
return plural(ms, msAbs, h, 'hour');
}
if (msAbs >= m) {
return plural(ms, msAbs, m, 'minute');
}
if (msAbs >= s) {
return plural(ms, msAbs, s, 'second');
}
return ms + ' ms';
}
/**
* Pluralization helper.
*/
function plural(ms, n, name) {
if (ms < n) {
return;
}
if (ms < n * 1.5) {
return Math.floor(ms / n) + ' ' + name;
}
return Math.ceil(ms / n) + ' ' + name + 's';
function plural(ms, msAbs, n, name) {
var isPlural = msAbs >= n * 1.5;
return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
}
+20 -25
View File
@@ -1,44 +1,39 @@
{
"_args": [
[
"ms@2.0.0",
"C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer"
]
],
"_from": "ms@2.0.0",
"_id": "ms@2.0.0",
"_from": "ms@^2.1.1",
"_id": "ms@2.1.2",
"_inBundle": false,
"_integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"_integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"_location": "/ms",
"_phantomChildren": {},
"_requested": {
"type": "version",
"type": "range",
"registry": true,
"raw": "ms@2.0.0",
"raw": "ms@^2.1.1",
"name": "ms",
"escapedName": "ms",
"rawSpec": "2.0.0",
"rawSpec": "^2.1.1",
"saveSpec": null,
"fetchSpec": "2.0.0"
"fetchSpec": "^2.1.1"
},
"_requiredBy": [
"/debug",
"/expand-brackets/debug",
"/snapdragon/debug"
"/debug"
],
"_resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"_spec": "2.0.0",
"_where": "C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer",
"_resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"_shasum": "d09d1f357b443f493382a8eb3ccd183872ae6009",
"_spec": "ms@^2.1.1",
"_where": "C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer\\node_modules\\debug",
"bugs": {
"url": "https://github.com/zeit/ms/issues"
},
"description": "Tiny milisecond conversion utility",
"bundleDependencies": false,
"deprecated": false,
"description": "Tiny millisecond conversion utility",
"devDependencies": {
"eslint": "3.19.0",
"eslint": "4.12.1",
"expect.js": "0.3.1",
"husky": "0.13.3",
"lint-staged": "3.4.1",
"mocha": "3.4.1"
"husky": "0.14.3",
"lint-staged": "5.0.0",
"mocha": "4.0.1"
},
"eslintConfig": {
"extends": "eslint:recommended",
@@ -70,5 +65,5 @@
"precommit": "lint-staged",
"test": "mocha tests.js"
},
"version": "2.0.0"
"version": "2.1.2"
}
+23 -5
View File
@@ -1,4 +1,4 @@
const TelegrafContext = require('./core/context')
const Context = require('./context')
class Composer {
constructor (...fns) {
@@ -100,9 +100,24 @@ class Composer {
return (ctx) => ctx.reply(...args)
}
static catchAll (...fns) {
return Composer.catch((err) => {
console.error()
console.error((err.stack || err.toString()).replace(/^/gm, ' '))
console.error()
}, ...fns)
}
static catch (errorHandler, ...fns) {
const handler = Composer.compose(fns)
return (ctx, next) => Promise.resolve(handler(ctx, next))
.catch((err) => errorHandler(err, ctx))
}
static fork (middleware) {
const handler = Composer.unwrap(middleware)
return (ctx, next) => {
setImmediate(Composer.unwrap(middleware), ctx, Composer.safePassThru())
setImmediate(handler, ctx, Composer.safePassThru())
return next(ctx)
}
}
@@ -317,7 +332,10 @@ class Composer {
}
static unwrap (handler) {
return handler && typeof handler.middleware === 'function'
if (!handler) {
throw new Error('Handler is undefined')
}
return typeof handler.middleware === 'function'
? handler.middleware()
: handler
}
@@ -336,14 +354,14 @@ class Composer {
let index = -1
return execute(0, ctx)
function execute (i, context) {
if (!(context instanceof TelegrafContext)) {
if (!(context instanceof Context)) {
return Promise.reject(new Error('next(ctx) called with invalid context'))
}
if (i <= index) {
return Promise.reject(new Error('next() called multiple times'))
}
index = i
const handler = Composer.unwrap(middlewares[i]) || next
const handler = middlewares[i] ? Composer.unwrap(middlewares[i]) : next
if (!handler) {
return Promise.resolve()
}
+568
View File
@@ -0,0 +1,568 @@
const UpdateTypes = [
'callback_query',
'channel_post',
'chosen_inline_result',
'edited_channel_post',
'edited_message',
'inline_query',
'shipping_query',
'pre_checkout_query',
'message',
'poll',
'poll_answer'
]
const MessageSubTypes = [
'voice',
'video_note',
'video',
'animation',
'venue',
'text',
'supergroup_chat_created',
'successful_payment',
'sticker',
'pinned_message',
'photo',
'new_chat_title',
'new_chat_photo',
'new_chat_members',
'migrate_to_chat_id',
'migrate_from_chat_id',
'location',
'left_chat_member',
'invoice',
'group_chat_created',
'game',
'document',
'delete_chat_photo',
'contact',
'channel_chat_created',
'audio',
'connected_website',
'passport_data',
'poll',
'forward_date'
]
const MessageSubTypesMapping = {
forward_date: 'forward'
}
class TelegrafContext {
constructor (update, telegram, options) {
this.tg = telegram
this.update = update
this.options = options
this.updateType = UpdateTypes.find((key) => key in this.update)
if (this.updateType === 'message' || (this.options.channelMode && this.updateType === 'channel_post')) {
this.updateSubTypes = MessageSubTypes
.filter((key) => key in this.update[this.updateType])
.map((type) => MessageSubTypesMapping[type] || type)
} else {
this.updateSubTypes = []
}
Object.getOwnPropertyNames(TelegrafContext.prototype)
.filter((key) => key !== 'constructor' && typeof this[key] === 'function')
.forEach((key) => (this[key] = this[key].bind(this)))
}
get me () {
return this.options && this.options.username
}
get telegram () {
return this.tg
}
get message () {
return this.update.message
}
get editedMessage () {
return this.update.edited_message
}
get inlineQuery () {
return this.update.inline_query
}
get shippingQuery () {
return this.update.shipping_query
}
get preCheckoutQuery () {
return this.update.pre_checkout_query
}
get chosenInlineResult () {
return this.update.chosen_inline_result
}
get channelPost () {
return this.update.channel_post
}
get editedChannelPost () {
return this.update.edited_channel_post
}
get callbackQuery () {
return this.update.callback_query
}
get poll () {
return this.update.poll
}
get pollAnswer () {
return this.update.poll_answer
}
get chat () {
return (this.message && this.message.chat) ||
(this.editedMessage && this.editedMessage.chat) ||
(this.callbackQuery && this.callbackQuery.message && this.callbackQuery.message.chat) ||
(this.channelPost && this.channelPost.chat) ||
(this.editedChannelPost && this.editedChannelPost.chat)
}
get from () {
return (this.message && this.message.from) ||
(this.editedMessage && this.editedMessage.from) ||
(this.callbackQuery && this.callbackQuery.from) ||
(this.inlineQuery && this.inlineQuery.from) ||
(this.channelPost && this.channelPost.from) ||
(this.editedChannelPost && this.editedChannelPost.from) ||
(this.shippingQuery && this.shippingQuery.from) ||
(this.preCheckoutQuery && this.preCheckoutQuery.from) ||
(this.chosenInlineResult && this.chosenInlineResult.from)
}
get inlineMessageId () {
return (this.callbackQuery && this.callbackQuery.inline_message_id) || (this.chosenInlineResult && this.chosenInlineResult.inline_message_id)
}
get passportData () {
return this.message && this.message.passport_data
}
get state () {
if (!this.contextState) {
this.contextState = {}
}
return this.contextState
}
set state (value) {
this.contextState = { ...value }
}
get webhookReply () {
return this.tg.webhookReply
}
set webhookReply (enable) {
this.tg.webhookReply = enable
}
assert (value, method) {
if (!value) {
throw new Error(`Telegraf: "${method}" isn't available for "${this.updateType}::${this.updateSubTypes}"`)
}
}
answerInlineQuery (...args) {
this.assert(this.inlineQuery, 'answerInlineQuery')
return this.telegram.answerInlineQuery(this.inlineQuery.id, ...args)
}
answerCbQuery (...args) {
this.assert(this.callbackQuery, 'answerCbQuery')
return this.telegram.answerCbQuery(this.callbackQuery.id, ...args)
}
answerGameQuery (...args) {
this.assert(this.callbackQuery, 'answerGameQuery')
return this.telegram.answerGameQuery(this.callbackQuery.id, ...args)
}
answerShippingQuery (...args) {
this.assert(this.shippingQuery, 'answerShippingQuery')
return this.telegram.answerShippingQuery(this.shippingQuery.id, ...args)
}
answerPreCheckoutQuery (...args) {
this.assert(this.preCheckoutQuery, 'answerPreCheckoutQuery')
return this.telegram.answerPreCheckoutQuery(this.preCheckoutQuery.id, ...args)
}
editMessageText (text, extra) {
this.assert(this.callbackQuery || this.inlineMessageId, 'editMessageText')
return this.inlineMessageId
? this.telegram.editMessageText(
undefined,
undefined,
this.inlineMessageId,
text,
extra
)
: this.telegram.editMessageText(
this.chat.id,
this.callbackQuery.message.message_id,
undefined,
text,
extra
)
}
editMessageCaption (caption, extra) {
this.assert(this.callbackQuery || this.inlineMessageId, 'editMessageCaption')
return this.inlineMessageId
? this.telegram.editMessageCaption(
undefined,
undefined,
this.inlineMessageId,
caption,
extra
)
: this.telegram.editMessageCaption(
this.chat.id,
this.callbackQuery.message.message_id,
undefined,
caption,
extra
)
}
editMessageMedia (media, extra) {
this.assert(this.callbackQuery || this.inlineMessageId, 'editMessageMedia')
return this.inlineMessageId
? this.telegram.editMessageMedia(
undefined,
undefined,
this.inlineMessageId,
media,
extra
)
: this.telegram.editMessageMedia(
this.chat.id,
this.callbackQuery.message.message_id,
undefined,
media,
extra
)
}
editMessageReplyMarkup (markup) {
this.assert(this.callbackQuery || this.inlineMessageId, 'editMessageReplyMarkup')
return this.inlineMessageId
? this.telegram.editMessageReplyMarkup(
undefined,
undefined,
this.inlineMessageId,
markup
)
: this.telegram.editMessageReplyMarkup(
this.chat.id,
this.callbackQuery.message.message_id,
undefined,
markup
)
}
editMessageLiveLocation (latitude, longitude, markup) {
this.assert(this.callbackQuery || this.inlineMessageId, 'editMessageLiveLocation')
return this.inlineMessageId
? this.telegram.editMessageLiveLocation(
latitude,
longitude,
undefined,
undefined,
this.inlineMessageId,
markup
)
: this.telegram.editMessageLiveLocation(
latitude,
longitude,
this.chat.id,
this.callbackQuery.message.message_id,
undefined,
markup
)
}
stopMessageLiveLocation (markup) {
this.assert(this.callbackQuery || this.inlineMessageId, 'stopMessageLiveLocation')
return this.inlineMessageId
? this.telegram.stopMessageLiveLocation(
undefined,
undefined,
this.inlineMessageId,
markup
)
: this.telegram.stopMessageLiveLocation(
this.chat.id,
this.callbackQuery.message.message_id,
undefined,
markup
)
}
reply (...args) {
this.assert(this.chat, 'reply')
return this.telegram.sendMessage(this.chat.id, ...args)
}
getChat (...args) {
this.assert(this.chat, 'getChat')
return this.telegram.getChat(this.chat.id, ...args)
}
exportChatInviteLink (...args) {
this.assert(this.chat, 'exportChatInviteLink')
return this.telegram.exportChatInviteLink(this.chat.id, ...args)
}
kickChatMember (...args) {
this.assert(this.chat, 'kickChatMember')
return this.telegram.kickChatMember(this.chat.id, ...args)
}
restrictChatMember (...args) {
this.assert(this.chat, 'restrictChatMember')
return this.telegram.restrictChatMember(this.chat.id, ...args)
}
promoteChatMember (...args) {
this.assert(this.chat, 'promoteChatMember')
return this.telegram.promoteChatMember(this.chat.id, ...args)
}
setChatAdministratorCustomTitle (...args) {
this.assert(this.chat, 'setChatAdministratorCustomTitle')
return this.telegram.setChatAdministratorCustomTitle(this.chat.id, ...args)
}
setChatPhoto (...args) {
this.assert(this.chat, 'setChatPhoto')
return this.telegram.setChatPhoto(this.chat.id, ...args)
}
deleteChatPhoto (...args) {
this.assert(this.chat, 'deleteChatPhoto')
return this.telegram.deleteChatPhoto(this.chat.id, ...args)
}
setChatTitle (...args) {
this.assert(this.chat, 'setChatTitle')
return this.telegram.setChatTitle(this.chat.id, ...args)
}
setChatDescription (...args) {
this.assert(this.chat, 'setChatDescription')
return this.telegram.setChatDescription(this.chat.id, ...args)
}
pinChatMessage (...args) {
this.assert(this.chat, 'pinChatMessage')
return this.telegram.pinChatMessage(this.chat.id, ...args)
}
unpinChatMessage (...args) {
this.assert(this.chat, 'unpinChatMessage')
return this.telegram.unpinChatMessage(this.chat.id, ...args)
}
leaveChat (...args) {
this.assert(this.chat, 'leaveChat')
return this.telegram.leaveChat(this.chat.id, ...args)
}
setChatPermissions (...args) {
this.assert(this.chat, 'setChatPermissions')
return this.telegram.setChatPermissions(this.chat.id, ...args)
}
getChatAdministrators (...args) {
this.assert(this.chat, 'getChatAdministrators')
return this.telegram.getChatAdministrators(this.chat.id, ...args)
}
getChatMember (...args) {
this.assert(this.chat, 'getChatMember')
return this.telegram.getChatMember(this.chat.id, ...args)
}
getChatMembersCount (...args) {
this.assert(this.chat, 'getChatMembersCount')
return this.telegram.getChatMembersCount(this.chat.id, ...args)
}
setPassportDataErrors (errors) {
this.assert(this.chat, 'setPassportDataErrors')
return this.telegram.setPassportDataErrors(this.from.id, errors)
}
replyWithPhoto (...args) {
this.assert(this.chat, 'replyWithPhoto')
return this.telegram.sendPhoto(this.chat.id, ...args)
}
replyWithMediaGroup (...args) {
this.assert(this.chat, 'replyWithMediaGroup')
return this.telegram.sendMediaGroup(this.chat.id, ...args)
}
replyWithAudio (...args) {
this.assert(this.chat, 'replyWithAudio')
return this.telegram.sendAudio(this.chat.id, ...args)
}
replyWithDocument (...args) {
this.assert(this.chat, 'replyWithDocument')
return this.telegram.sendDocument(this.chat.id, ...args)
}
replyWithSticker (...args) {
this.assert(this.chat, 'replyWithSticker')
return this.telegram.sendSticker(this.chat.id, ...args)
}
replyWithVideo (...args) {
this.assert(this.chat, 'replyWithVideo')
return this.telegram.sendVideo(this.chat.id, ...args)
}
replyWithAnimation (...args) {
this.assert(this.chat, 'replyWithAnimation')
return this.telegram.sendAnimation(this.chat.id, ...args)
}
replyWithVideoNote (...args) {
this.assert(this.chat, 'replyWithVideoNote')
return this.telegram.sendVideoNote(this.chat.id, ...args)
}
replyWithInvoice (...args) {
this.assert(this.chat, 'replyWithInvoice')
return this.telegram.sendInvoice(this.chat.id, ...args)
}
replyWithGame (...args) {
this.assert(this.chat, 'replyWithGame')
return this.telegram.sendGame(this.chat.id, ...args)
}
replyWithVoice (...args) {
this.assert(this.chat, 'replyWithVoice')
return this.telegram.sendVoice(this.chat.id, ...args)
}
replyWithPoll (...args) {
this.assert(this.chat, 'replyWithPoll')
return this.telegram.sendPoll(this.chat.id, ...args)
}
replyWithQuiz (...args) {
this.assert(this.chat, 'replyWithQuiz')
return this.telegram.sendQuiz(this.chat.id, ...args)
}
stopPoll (...args) {
this.assert(this.chat, 'stopPoll')
return this.telegram.stopPoll(this.chat.id, ...args)
}
replyWithChatAction (...args) {
this.assert(this.chat, 'replyWithChatAction')
return this.telegram.sendChatAction(this.chat.id, ...args)
}
replyWithLocation (...args) {
this.assert(this.chat, 'replyWithLocation')
return this.telegram.sendLocation(this.chat.id, ...args)
}
replyWithVenue (...args) {
this.assert(this.chat, 'replyWithVenue')
return this.telegram.sendVenue(this.chat.id, ...args)
}
replyWithContact (...args) {
this.assert(this.from, 'replyWithContact')
return this.telegram.sendContact(this.chat.id, ...args)
}
getStickerSet (setName) {
return this.telegram.getStickerSet(setName)
}
setChatStickerSet (setName) {
this.assert(this.chat, 'setChatStickerSet')
return this.telegram.setChatStickerSet(this.chat.id, setName)
}
deleteChatStickerSet () {
this.assert(this.chat, 'deleteChatStickerSet')
return this.telegram.deleteChatStickerSet(this.chat.id)
}
setStickerPositionInSet (sticker, position) {
return this.telegram.setStickerPositionInSet(sticker, position)
}
deleteStickerFromSet (sticker) {
return this.telegram.deleteStickerFromSet(sticker)
}
uploadStickerFile (...args) {
this.assert(this.from, 'uploadStickerFile')
return this.telegram.uploadStickerFile(this.from.id, ...args)
}
createNewStickerSet (...args) {
this.assert(this.from, 'createNewStickerSet')
return this.telegram.createNewStickerSet(this.from.id, ...args)
}
addStickerToSet (...args) {
this.assert(this.from, 'addStickerToSet')
return this.telegram.addStickerToSet(this.from.id, ...args)
}
replyWithMarkdown (markdown, extra) {
return this.reply(markdown, { parse_mode: 'Markdown', ...extra })
}
replyWithHTML (html, extra) {
return this.reply(html, { parse_mode: 'HTML', ...extra })
}
deleteMessage (messageId) {
this.assert(this.chat, 'deleteMessage')
if (typeof messageId !== 'undefined') {
return this.telegram.deleteMessage(this.chat.id, messageId)
}
const message = this.message ||
this.editedMessage ||
this.channelPost ||
this.editedChannelPost ||
(this.callbackQuery && this.callbackQuery.message)
this.assert(message, 'deleteMessage')
return this.telegram.deleteMessage(this.chat.id, message.message_id)
}
forwardMessage (chatId, extra) {
this.assert(this.chat, 'forwardMessage')
const message = this.message ||
this.editedMessage ||
this.channelPost ||
this.editedChannelPost ||
(this.callbackQuery && this.callbackQuery.message)
this.assert(message, 'forwardMessage')
return this.telegram.forwardMessage(chatId, this.chat.id, message.message_id, extra)
}
}
module.exports = TelegrafContext
+50 -32
View File
@@ -8,7 +8,7 @@ const TelegramError = require('./error')
const MultipartStream = require('./multipart-stream')
const { isStream } = MultipartStream
const WebhookBlacklist = [
const WEBHOOK_BLACKLIST = [
'getChat',
'getChatAdministrators',
'getChatMember',
@@ -22,7 +22,7 @@ const WebhookBlacklist = [
'exportChatInviteLink'
]
const DefaultExtensions = {
const DEFAULT_EXTENSIONS = {
audio: 'mp3',
photo: 'jpg',
sticker: 'webp',
@@ -32,7 +32,7 @@ const DefaultExtensions = {
voice: 'ogg'
}
const DefaultOptions = {
const DEFAULT_OPTIONS = {
apiRoot: 'https://api.telegram.org',
webhookReply: true,
agent: new https.Agent({
@@ -41,7 +41,7 @@ const DefaultOptions = {
})
}
const WebhookReplyStub = {
const WEBHOOK_REPLY_STUB = {
webhook: true,
details: 'https://core.telegram.org/bots/api#making-requests-when-getting-updates'
}
@@ -79,13 +79,23 @@ function buildJSONConfig (payload) {
})
}
function buildFormDataConfig (payload) {
if (payload.reply_markup && typeof payload.reply_markup !== 'string') {
payload.reply_markup = JSON.stringify(payload.reply_markup)
const FORM_DATA_JSON_FIELDS = [
'results',
'reply_markup',
'mask_position',
'shipping_options',
'errors'
]
function buildFormDataConfig (payload, agent) {
for (const field of FORM_DATA_JSON_FIELDS) {
if (field in payload && typeof payload[field] !== 'string') {
payload[field] = JSON.stringify(payload[field])
}
}
const boundary = crypto.randomBytes(32).toString('hex')
const formData = new MultipartStream(boundary)
const tasks = Object.keys(payload).map((key) => attachFormValue(formData, key, payload[key]))
const tasks = Object.keys(payload).map((key) => attachFormValue(formData, key, payload[key], agent))
return Promise.all(tasks).then(() => {
return {
method: 'POST',
@@ -96,7 +106,7 @@ function buildFormDataConfig (payload) {
})
}
function attachFormValue (form, id, value) {
function attachFormValue (form, id, value, agent) {
if (!value) {
return Promise.resolve()
}
@@ -110,7 +120,7 @@ function attachFormValue (form, id, value) {
}
if (id === 'thumb') {
const attachmentId = crypto.randomBytes(16).toString('hex')
return attachFormMedia(form, value, attachmentId)
return attachFormMedia(form, value, attachmentId, agent)
.then(() => form.addPart({
headers: { 'content-disposition': `form-data; name="${id}"` },
body: `attach://${attachmentId}`
@@ -123,8 +133,8 @@ function attachFormValue (form, id, value) {
return Promise.resolve(item)
}
const attachmentId = crypto.randomBytes(16).toString('hex')
return attachFormMedia(form, item.media, attachmentId)
.then(() => Object.assign({}, item, { media: `attach://${attachmentId}` }))
return attachFormMedia(form, item.media, attachmentId, agent)
.then(() => ({ ...item, media: `attach://${attachmentId}` }))
})
).then((items) => form.addPart({
headers: { 'content-disposition': `form-data; name="${id}"` },
@@ -133,21 +143,22 @@ function attachFormValue (form, id, value) {
}
if (typeof value.media !== 'undefined' && typeof value.type !== 'undefined') {
const attachmentId = crypto.randomBytes(16).toString('hex')
return attachFormMedia(form, value.media, attachmentId)
return attachFormMedia(form, value.media, attachmentId, agent)
.then(() => form.addPart({
headers: { 'content-disposition': `form-data; name="${id}"` },
body: JSON.stringify(Object.assign(value, {
body: JSON.stringify({
...value,
media: `attach://${attachmentId}`
}))
})
}))
}
return attachFormMedia(form, value, id)
return attachFormMedia(form, value, id, agent)
}
function attachFormMedia (form, media, id) {
let fileName = media.filename || `${id}.${DefaultExtensions[id] || 'dat'}`
function attachFormMedia (form, media, id, agent) {
let fileName = media.filename || `${id}.${DEFAULT_EXTENSIONS[id] || 'dat'}`
if (media.url) {
return fetch(media.url).then((res) =>
return fetch(media.url, { agent }).then((res) =>
form.addPart({
headers: { 'content-disposition': `form-data; name="${id}"; filename="${fileName}"` },
body: res.body
@@ -173,32 +184,36 @@ function isKoaResponse (response) {
return typeof response.set === 'function' && typeof response.header === 'object'
}
function answerToWebhook (response, payload = {}) {
function answerToWebhook (response, payload = {}, options) {
if (!includesMedia(payload)) {
if (isKoaResponse(response)) {
response.body = payload
return Promise.resolve(WebhookReplyStub)
return Promise.resolve(WEBHOOK_REPLY_STUB)
}
if (!response.headersSent) {
response.setHeader('content-type', 'application/json')
}
return new Promise((resolve) =>
response.end(JSON.stringify(payload), 'utf-8', () => resolve(WebhookReplyStub))
)
return new Promise((resolve) => {
if (response.end.length === 2) {
response.end(JSON.stringify(payload), 'utf-8')
return resolve(WEBHOOK_REPLY_STUB)
}
response.end(JSON.stringify(payload), 'utf-8', () => resolve(WEBHOOK_REPLY_STUB))
})
}
return buildFormDataConfig(payload)
return buildFormDataConfig(payload, options.agent)
.then(({ headers, body }) => {
if (isKoaResponse(response)) {
Object.keys(headers).forEach(key => response.set(key, headers[key]))
response.body = body
return Promise.resolve(WebhookReplyStub)
return Promise.resolve(WEBHOOK_REPLY_STUB)
}
if (!response.headersSent) {
Object.keys(headers).forEach(key => response.setHeader(key, headers[key]))
}
return new Promise((resolve) => {
response.on('finish', () => resolve(WebhookReplyStub))
response.on('finish', () => resolve(WEBHOOK_REPLY_STUB))
body.pipe(response)
})
})
@@ -207,7 +222,10 @@ function answerToWebhook (response, payload = {}) {
class ApiClient {
constructor (token, options, webhookResponse) {
this.token = token
this.options = Object.assign({}, DefaultOptions, options)
this.options = {
...DEFAULT_OPTIONS,
...options
}
if (this.options.apiRoot.startsWith('http://')) {
this.options.agent = null
}
@@ -227,12 +245,12 @@ class ApiClient {
const payload = Object.keys(data)
.filter((key) => typeof data[key] !== 'undefined' && data[key] !== null)
.reduce((acc, key) => Object.assign(acc, { [key]: data[key] }), {})
.reduce((acc, key) => ({ ...acc, [key]: data[key] }), {})
if (options.webhookReply && response && !responseEnd && !WebhookBlacklist.includes(method)) {
if (options.webhookReply && response && !responseEnd && !WEBHOOK_BLACKLIST.includes(method)) {
debug('Call via webhook', method, payload)
this.responseEnd = true
return answerToWebhook(response, Object.assign({ method }, payload))
return answerToWebhook(response, { method, ...payload }, options)
}
if (!token) {
@@ -241,7 +259,7 @@ class ApiClient {
debug('HTTP call', method, payload)
const buildConfig = includesMedia(payload)
? buildFormDataConfig(Object.assign({ method }, payload))
? buildFormDataConfig({ method, ...payload }, options.agent)
: buildJSONConfig(payload)
return buildConfig
.then((config) => {
+31 -30
View File
@@ -1,26 +1,4 @@
function wrapEntity (content, entity) {
switch (entity.type) {
case 'bold':
return `<b>${content}</b>`
case 'italic':
return `<i>${content}</i>`
case 'code':
return `<code>${content}</code>`
case 'pre':
return `<pre>${content}</pre>`
case 'text_link':
return `<a href="${entity.url}">${content}</a>`
default:
return content
}
}
function applyEntity (text, entity) {
const head = text.substring(0, entity.offset)
const tail = text.substring(entity.offset + entity.length)
const content = wrapEntity(text.substring(entity.offset, entity.offset + entity.length), entity)
return `${head}${content}${tail}`
}
const { formatHTML } = require('../markup')
module.exports = {
copyMethods: {
@@ -35,17 +13,20 @@ module.exports = {
video: 'sendVideo',
video_note: 'sendVideoNote',
animation: 'sendAnimation',
voice: 'sendVoice'
voice: 'sendVoice',
poll: 'sendPoll'
},
text: (message) => {
const entities = message.entities || []
return {
reply_markup: message.reply_markup,
parse_mode: entities.length > 0 ? 'HTML' : '',
text: entities.reduceRight(applyEntity, message.text)
text: formatHTML(message.text, entities)
}
},
contact: (message) => {
return {
reply_markup: message.reply_markup,
phone_number: message.contact.phone_number,
first_name: message.contact.first_name,
last_name: message.contact.last_name
@@ -53,12 +34,14 @@ module.exports = {
},
location: (message) => {
return {
reply_markup: message.reply_markup,
latitude: message.location.latitude,
longitude: message.location.longitude
}
},
venue: (message) => {
return {
reply_markup: message.reply_markup,
latitude: message.venue.location.latitude,
longitude: message.venue.location.longitude,
title: message.venue.title,
@@ -69,30 +52,33 @@ module.exports = {
voice: (message) => {
const entities = message.caption_entities || []
return {
reply_markup: message.reply_markup,
voice: message.voice.file_id,
duration: message.voice.duration,
caption: entities.reduceRight(applyEntity, message.caption),
caption: formatHTML(message.caption, entities),
parse_mode: entities.length > 0 ? 'HTML' : ''
}
},
audio: (message) => {
const entities = message.caption_entities || []
return {
reply_markup: message.reply_markup,
audio: message.audio.file_id,
thumb: message.audio.thumb,
duration: message.audio.duration,
performer: message.audio.performer,
title: message.audio.title,
caption: entities.reduceRight(applyEntity, message.caption),
caption: formatHTML(message.caption, entities),
parse_mode: entities.length > 0 ? 'HTML' : ''
}
},
video: (message) => {
const entities = message.caption_entities || []
return {
reply_markup: message.reply_markup,
video: message.video.file_id,
thumb: message.video.thumb,
caption: entities.reduceRight(applyEntity, message.caption),
caption: formatHTML(message.caption, entities),
parse_mode: entities.length > 0 ? 'HTML' : '',
duration: message.video.duration,
width: message.video.width,
@@ -103,26 +89,30 @@ module.exports = {
document: (message) => {
const entities = message.caption_entities || []
return {
reply_markup: message.reply_markup,
document: message.document.file_id,
caption: entities.reduceRight(applyEntity, message.caption),
caption: formatHTML(message.caption, entities),
parse_mode: entities.length > 0 ? 'HTML' : ''
}
},
sticker: (message) => {
return {
reply_markup: message.reply_markup,
sticker: message.sticker.file_id
}
},
photo: (message) => {
const entities = message.caption_entities || []
return {
reply_markup: message.reply_markup,
photo: message.photo[message.photo.length - 1].file_id,
parse_mode: entities.length > 0 ? 'HTML' : '',
caption: entities.reduceRight(applyEntity, message.caption)
caption: formatHTML(message.caption, entities)
}
},
video_note: (message) => {
return {
reply_markup: message.reply_markup,
video_note: message.video_note.file_id,
thumb: message.video_note.thumb,
length: message.video_note.length,
@@ -131,9 +121,20 @@ module.exports = {
},
animation: (message) => {
return {
reply_markup: message.reply_markup,
animation: message.animation.file_id,
thumb: message.animation.thumb,
duration: message.animation.duration
}
},
poll: (message) => {
return {
question: message.poll.question,
type: message.poll.type,
is_anonymous: message.poll.is_anonymous,
allows_multiple_answers: message.poll.allows_multiple_answers,
correct_option_id: message.poll.correct_option_id,
options: message.poll.options.map(({ text }) => text)
}
}
}
+3 -3
View File
@@ -5,8 +5,8 @@ class Extra {
this.load(opts)
}
load (opts) {
return Object.assign(this, opts || {})
load (opts = {}) {
return Object.assign(this, opts)
}
inReplyTo (messageId) {
@@ -28,7 +28,7 @@ class Extra {
if (typeof markup === 'function') {
markup = markup(new Markup())
}
this.reply_markup = Object.assign({}, markup)
this.reply_markup = { ...markup }
return this
}
+87 -6
View File
@@ -15,13 +15,14 @@ class Markup {
}
extra (options) {
return Object.assign({
reply_markup: Object.assign({}, this)
}, options)
return {
reply_markup: { ...this },
...options
}
}
keyboard (buttons, options) {
const keyboard = buildKeyboard(buttons, Object.assign({ columns: 1 }, options))
const keyboard = buildKeyboard(buttons, { columns: 1, ...options })
if (keyboard && keyboard.length > 0) {
this.keyboard = keyboard
}
@@ -39,7 +40,7 @@ class Markup {
}
inlineKeyboard (buttons, options) {
const keyboard = buildKeyboard(buttons, Object.assign({ columns: buttons.length }, options))
const keyboard = buildKeyboard(buttons, { columns: buttons.length, ...options })
if (keyboard && keyboard.length > 0) {
this.inline_keyboard = keyboard
}
@@ -126,6 +127,10 @@ class Markup {
return { text: text, request_location: true, hide: hide }
}
static pollRequestButton (text, type, hide = false) {
return { text: text, request_poll: { type }, hide: hide }
}
static urlButton (text, url, hide = false) {
return { text: text, url: url, hide: hide }
}
@@ -153,10 +158,86 @@ class Markup {
static loginButton (text, url, opts = {}, hide = false) {
return {
text: text,
login_url: Object.assign({}, opts, { url: url }),
login_url: { ...opts, url: url },
hide: hide
}
}
static formatHTML (text, entities) {
const chars = [...text]
const available = [...entities]
const opened = []
const result = []
for (let offset = 0; offset < chars.length; offset++) {
while (true) {
const index = available.findIndex((entity) => entity.offset === offset)
if (index === -1) {
break
}
const entity = available[index]
switch (entity.type) {
case 'bold':
result.push('<b>')
break
case 'italic':
result.push('<i>')
break
case 'code':
result.push('<code>')
break
case 'pre':
result.push('<pre>')
break
case 'strikethrough':
result.push('<s>')
break
case 'underline':
result.push('<u>')
break
case 'text_link':
result.push(`<a href="${entity.url}">`)
break
}
opened.unshift(entity)
available.splice(index, 1)
}
result.push(chars[offset])
while (true) {
const index = opened.findIndex((entity) => entity.offset + entity.length - 1 === offset)
if (index === -1) {
break
}
const entity = opened[index]
switch (entity.type) {
case 'bold':
result.push('</b>')
break
case 'italic':
result.push('</i>')
break
case 'code':
result.push('</code>')
break
case 'pre':
result.push('</pre>')
break
case 'strikethrough':
result.push('</s>')
break
case 'underline':
result.push('</u>')
break
case 'text_link':
result.push('</a>')
break
}
opened.splice(index, 1)
}
}
return result.join('')
}
}
function buildKeyboard (buttons, options) {
+26 -19
View File
@@ -1,61 +1,67 @@
{
"_from": "telegraf",
"_id": "telegraf@3.32.0",
"_from": "telegraf@3.36.0",
"_id": "telegraf@3.36.0",
"_inBundle": false,
"_integrity": "sha512-5ZHiovyuG1rVLygJjaqf57wDt8e1nijAinKXCxN1tyUZ4BcrkZW/z5rVTEXA+KegpFbWxKKv3KnJwUJrKDqD0Q==",
"_integrity": "sha512-9o6AJKRiTm5vMWYI6WpTfBHzu4FMpWBNKxvnMxRds/cbMY9RnsVVjdi8i4bFFlfd+xbi73EbrnI3dybayryICA==",
"_location": "/telegraf",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"type": "version",
"registry": true,
"raw": "telegraf",
"raw": "telegraf@3.36.0",
"name": "telegraf",
"escapedName": "telegraf",
"rawSpec": "",
"rawSpec": "3.36.0",
"saveSpec": null,
"fetchSpec": "latest"
"fetchSpec": "3.36.0"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/telegraf/-/telegraf-3.32.0.tgz",
"_shasum": "70ec304b9c8645f8988924ebe90e5c00ee46ddbb",
"_spec": "telegraf",
"_resolved": "https://registry.npmjs.org/telegraf/-/telegraf-3.36.0.tgz",
"_shasum": "eab1160159df6033d3cb92ac990902523277822a",
"_spec": "telegraf@3.36.0",
"_where": "C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer",
"author": {
"name": "Vitaly Domnikov",
"email": "oss@vitaly.codes"
},
"bin": {
"telegraf": "./bin/telegraf"
},
"bugs": {
"url": "https://github.com/telegraf/telegraf/issues"
},
"bundleDependencies": false,
"dependencies": {
"@types/node": "^12.0.4",
"@types/node": "^13.1.0",
"debug": "^4.0.1",
"minimist": "^1.2.0",
"module-alias": "^2.2.2",
"node-fetch": "^2.2.0",
"sandwich-stream": "^2.0.1",
"telegram-typings": "^3.6.0"
},
"deprecated": false,
"description": "📡 Modern Telegram Bot Framework",
"description": "Modern Telegram Bot Framework",
"devDependencies": {
"ava": "^2.2.0",
"eslint": "^6.1.0",
"eslint-config-standard": "^13.0.1",
"eslint-plugin-ava": "^7.1.0",
"ava": "^3.0.0",
"eslint": "^6.2.2",
"eslint-config-standard": "^14.1.0",
"eslint-plugin-ava": "^10.0.0",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-node": "^9.1.0",
"eslint-plugin-node": "^11.0.0",
"eslint-plugin-promise": "^4.0.0",
"eslint-plugin-standard": "^4.0.0",
"husky": "^3.0.2",
"husky": "^4.2.0",
"typescript": "^3.0.1"
},
"engines": {
"node": ">=8"
},
"files": [
"bin/*",
"core/**/*.js",
"scenes/**/*.js",
"typings/*.d.ts",
@@ -83,6 +89,7 @@
"test": "ava test/*",
"typecheck": "tsc"
},
"type": "commonjs",
"types": "./typings/index.d.ts",
"version": "3.32.0"
"version": "3.36.0"
}
+4 -3
View File
@@ -3,11 +3,12 @@ const { compose } = Composer
class BaseScene extends Composer {
constructor (id, options) {
const opts = Object.assign({
const opts = {
handlers: [],
enterHandlers: [],
leaveHandlers: []
}, options)
leaveHandlers: [],
...options
}
super(...opts.handlers)
this.id = id
this.options = opts
+1 -1
View File
@@ -27,7 +27,7 @@ class SceneContext {
}
set state (value) {
this.session.state = Object.assign({}, value)
this.session.state = { ...value }
}
get current () {
+1 -1
View File
@@ -8,7 +8,7 @@ class WizardScene extends Composer {
this.id = id
this.options = typeof options === 'function'
? { steps: [options, ...steps], leaveHandlers: [] }
: Object.assign({ steps: steps, leaveHandlers: [] }, options)
: { steps: steps, leaveHandlers: [], ...options }
this.leaveHandler = compose(this.options.leaveHandlers)
}
+5 -4
View File
@@ -1,9 +1,10 @@
module.exports = function (opts) {
const options = Object.assign({
const options = {
property: 'session',
store: new Map(),
getSessionKey: (ctx) => ctx.from && ctx.chat && `${ctx.from.id}:${ctx.chat.id}`
}, opts)
getSessionKey: (ctx) => ctx.from && ctx.chat && `${ctx.from.id}:${ctx.chat.id}`,
...opts
}
const ttlMs = options.ttl && options.ttl * 1000
@@ -21,7 +22,7 @@ module.exports = function (opts) {
}
Object.defineProperty(ctx, options.property, {
get: function () { return session },
set: function (newValue) { session = Object.assign({}, newValue) }
set: function (newValue) { session = { ...newValue } }
})
return next(ctx).then(() => options.store.set(key, {
session,
+4 -3
View File
@@ -5,9 +5,10 @@ const { compose, optional, lazy, safePassThru } = Composer
class Stage extends Composer {
constructor (scenes = [], options) {
super()
this.options = Object.assign({
sessionName: 'session'
}, options)
this.options = {
sessionName: 'session',
...options
}
this.scenes = new Map()
scenes.forEach((scene) => this.register(scene))
}
+42 -18
View File
@@ -5,14 +5,17 @@ const Composer = require('./composer')
const Markup = require('./markup')
const session = require('./session')
const Router = require('./router')
const Context = require('./core/context')
const Stage = require('./stage')
const BaseScene = require('./scenes/base')
const Context = require('./context')
const generateCallback = require('./core/network/webhook')
const crypto = require('crypto')
const { URL } = require('url')
const DefaultOptions = {
const DEFAULT_OPTIONS = {
retryAfter: 1,
handlerTimeout: 0
handlerTimeout: 0,
contextType: Context
}
const noop = () => { }
@@ -20,7 +23,10 @@ const noop = () => { }
class Telegraf extends Composer {
constructor (token, options) {
super()
this.options = Object.assign({}, DefaultOptions, options)
this.options = {
...DEFAULT_OPTIONS,
...options
}
this.token = token
this.handleError = (err) => {
console.error()
@@ -92,6 +98,7 @@ class Telegraf extends Composer {
}
launch (config = {}) {
debug('Connecting to Telegram')
return this.telegram.getMe()
.then((botInfo) => {
debug(`Launching @${botInfo.username}`)
@@ -101,7 +108,7 @@ class Telegraf extends Composer {
const { timeout, limit, allowedUpdates, stopCallback } = config.polling || {}
return this.telegram.deleteWebhook()
.then(() => this.startPolling(timeout, limit, allowedUpdates, stopCallback))
.then(() => debug(`Bot started with long-polling`))
.then(() => debug('Bot started with long-polling'))
}
if (typeof config.webhook.domain !== 'string' && typeof config.webhook.hookPath !== 'string') {
throw new Error('Webhook domain or webhook path is required')
@@ -114,23 +121,31 @@ class Telegraf extends Composer {
const { port, host, tlsOptions, cb } = config.webhook
this.startWebhook(hookPath, tlsOptions, port, host, cb)
if (!domain) {
debug(`Bot started with webhook`)
debug('Bot started with webhook')
return
}
return this.telegram
.setWebhook(`https://${domain}${hookPath}`)
.then(() => debug(`Bot started with webhook @ https://${domain}`))
})
.catch((err) => {
console.error('Launch failed')
console.error(err.stack || err.toString())
})
}
stop (cb = noop) {
this.polling.started = false
if (this.webhookServer) {
this.webhookServer.close(cb)
} else {
cb()
}
return this
debug('Stopping bot...')
return new Promise((resolve) => {
const done = () => resolve() & cb()
if (this.webhookServer) {
return this.webhookServer.close(done)
} else if (!this.polling.started) {
return done()
}
this.polling.stopCallback = done
this.polling.started = false
})
}
handleUpdates (updates) {
@@ -150,16 +165,18 @@ class Telegraf extends Composer {
handleUpdate (update, webhookResponse) {
debug('Processing update', update.update_id)
const tg = new Telegram(this.token, this.telegram.options, webhookResponse)
const ctx = new Context(update, tg, this.options)
const TelegrafContext = this.options.contextType
const ctx = new TelegrafContext(update, tg, this.options)
Object.assign(ctx, this.context)
return this.middleware()(ctx).catch(this.handleError)
return this.middleware()(ctx).catch((err) => this.handleError(err, ctx))
}
fetchUpdates () {
const { timeout, limit, offset, started, allowedUpdates } = this.polling
if (!started) {
if (!this.polling.started) {
this.polling.stopCallback && this.polling.stopCallback()
return
}
const { timeout, limit, offset, allowedUpdates } = this.polling
this.telegram.getUpdates(timeout, limit, offset, allowedUpdates)
.catch((err) => {
if (err.code === 401 || err.code === 409) {
@@ -169,7 +186,10 @@ class Telegraf extends Composer {
console.error(`Failed to fetch updates. Waiting: ${wait}s`, err.message)
return new Promise((resolve) => setTimeout(resolve, wait * 1000, []))
})
.then((updates) => this.handleUpdates(updates).then(() => updates))
.then((updates) => this.polling.started
? this.handleUpdates(updates).then(() => updates)
: []
)
.catch((err) => {
console.error('Failed to process updates.', err)
this.polling.started = false
@@ -187,6 +207,7 @@ class Telegraf extends Composer {
}
module.exports = Object.assign(Telegraf, {
Context,
Composer,
Extra,
Markup,
@@ -196,10 +217,13 @@ module.exports = Object.assign(Telegraf, {
})
module.exports.default = Object.assign(Telegraf, {
Context,
Composer,
Extra,
Markup,
Router,
Telegram,
Stage,
BaseScene,
session
})
+96 -84
View File
@@ -1,4 +1,3 @@
const util = require('util')
const replicators = require('./core/replicators')
const ApiClient = require('./core/network/client')
@@ -31,11 +30,11 @@ class Telegram extends ApiClient {
}
getWebhookInfo () {
return this.callApi(`getWebhookInfo`)
return this.callApi('getWebhookInfo')
}
getGameHighScores (userId, inlineMessageId, chatId, messageId) {
return this.callApi(`getGameHighScores`, {
return this.callApi('getGameHighScores', {
user_id: userId,
inline_message_id: inlineMessageId,
chat_id: chatId,
@@ -44,21 +43,21 @@ class Telegram extends ApiClient {
}
setGameScore (userId, score, inlineMessageId, chatId, messageId, editMessage = true, force) {
return this.callApi(`setGameScore`, {
return this.callApi('setGameScore', {
force,
score,
user_id: userId,
score: score,
inline_message_id: inlineMessageId,
chat_id: chatId,
message_id: messageId,
disable_edit_message: !editMessage,
force: force
disable_edit_message: !editMessage
})
}
setWebhook (url, cert, maxConnections, allowedUpdates) {
setWebhook (url, certificate, maxConnections, allowedUpdates) {
return this.callApi('setWebhook', {
url: url,
certificate: cert,
url,
certificate,
max_connections: maxConnections,
allowed_updates: allowedUpdates
})
@@ -69,93 +68,99 @@ class Telegram extends ApiClient {
}
sendMessage (chatId, text, extra) {
return this.callApi('sendMessage', Object.assign({ chat_id: chatId, text: text }, extra))
return this.callApi('sendMessage', { chat_id: chatId, text, ...extra })
}
forwardMessage (chatId, fromChatId, messageId, extra) {
return this.callApi('forwardMessage', Object.assign({
return this.callApi('forwardMessage', {
chat_id: chatId,
from_chat_id: fromChatId,
message_id: messageId
}, extra))
message_id: messageId,
...extra
})
}
sendChatAction (chatId, action) {
return this.callApi('sendChatAction', { chat_id: chatId, action: action })
return this.callApi('sendChatAction', { chat_id: chatId, action })
}
getUserProfilePhotos (userId, offset, limit) {
return this.callApi('getUserProfilePhotos', { user_id: userId, offset: offset, limit: limit })
return this.callApi('getUserProfilePhotos', { user_id: userId, offset, limit })
}
sendLocation (chatId, latitude, longitude, extra) {
return this.callApi('sendLocation', Object.assign({ chat_id: chatId, latitude: latitude, longitude: longitude }, extra))
return this.callApi('sendLocation', { chat_id: chatId, latitude, longitude, ...extra })
}
sendVenue (chatId, latitude, longitude, title, address, extra) {
return this.callApi('sendVenue', Object.assign({
return this.callApi('sendVenue', {
latitude,
longitude,
title,
address,
chat_id: chatId,
latitude: latitude,
longitude: longitude,
title: title,
address: address
}, extra))
...extra
})
}
sendInvoice (chatId, invoice, extra) {
return this.callApi('sendInvoice', Object.assign({ chat_id: chatId }, invoice, extra))
return this.callApi('sendInvoice', { chat_id: chatId, ...invoice, ...extra })
}
sendContact (chatId, phoneNumber, firstName, extra) {
return this.callApi('sendContact', Object.assign({ chat_id: chatId, phone_number: phoneNumber, first_name: firstName }, extra))
return this.callApi('sendContact', { chat_id: chatId, phone_number: phoneNumber, first_name: firstName, ...extra })
}
sendPhoto (chatId, photo, extra) {
return this.callApi('sendPhoto', Object.assign({ chat_id: chatId, photo: photo }, extra))
return this.callApi('sendPhoto', { chat_id: chatId, photo, ...extra })
}
sendDocument (chatId, doc, extra) {
return this.callApi('sendDocument', Object.assign({ chat_id: chatId, document: doc }, extra))
sendDocument (chatId, document, extra) {
return this.callApi('sendDocument', { chat_id: chatId, document, ...extra })
}
sendAudio (chatId, audio, extra) {
return this.callApi('sendAudio', Object.assign({ chat_id: chatId, audio: audio }, extra))
return this.callApi('sendAudio', { chat_id: chatId, audio, ...extra })
}
sendSticker (chatId, sticker, extra) {
return this.callApi('sendSticker', Object.assign({ chat_id: chatId, sticker: sticker }, extra))
return this.callApi('sendSticker', { chat_id: chatId, sticker, ...extra })
}
sendVideo (chatId, video, extra) {
return this.callApi('sendVideo', Object.assign({ chat_id: chatId, video: video }, extra))
return this.callApi('sendVideo', { chat_id: chatId, video, ...extra })
}
sendAnimation (chatId, animation, extra) {
return this.callApi('sendAnimation', Object.assign({ chat_id: chatId, animation: animation }, extra))
return this.callApi('sendAnimation', { chat_id: chatId, animation, ...extra })
}
sendVideoNote (chatId, videoNote, extra) {
return this.callApi('sendVideoNote', Object.assign({ chat_id: chatId, video_note: videoNote }, extra))
return this.callApi('sendVideoNote', { chat_id: chatId, video_note: videoNote, ...extra })
}
sendVoice (chatId, voice, extra) {
return this.callApi('sendVoice', Object.assign({ chat_id: chatId, voice: voice }, extra))
return this.callApi('sendVoice', { chat_id: chatId, voice, ...extra })
}
sendGame (chatId, gameName, extra) {
return this.callApi('sendGame', Object.assign({ chat_id: chatId, game_short_name: gameName }, extra))
return this.callApi('sendGame', { chat_id: chatId, game_short_name: gameName, ...extra })
}
sendMediaGroup (chatId, media, extra) {
return this.callApi('sendMediaGroup', Object.assign({ chat_id: chatId, media }, extra))
return this.callApi('sendMediaGroup', { chat_id: chatId, media, ...extra })
}
sendPoll (chatId, question, options, extra) {
return this.callApi('sendPoll', Object.assign({ chat_id: chatId, question, options }, extra))
return this.callApi('sendPoll', { chat_id: chatId, type: 'regular', question, options, ...extra })
}
sendQuiz (chatId, question, options, extra) {
return this.callApi('sendPoll', { chat_id: chatId, type: 'quiz', question, options, ...extra })
}
stopPoll (chatId, messageId, extra) {
return this.callApi('stopPoll', Object.assign({ chat_id: chatId, message_id: messageId }, extra))
return this.callApi('stopPoll', { chat_id: chatId, message_id: messageId, ...extra })
}
getChat (chatId) {
@@ -175,7 +180,7 @@ class Telegram extends ApiClient {
}
answerInlineQuery (inlineQueryId, results, extra) {
return this.callApi('answerInlineQuery', Object.assign({ inline_query_id: inlineQueryId, results: JSON.stringify(results) }, extra))
return this.callApi('answerInlineQuery', { inline_query_id: inlineQueryId, results, ...extra })
}
setChatPermissions (chatId, permissions) {
@@ -187,11 +192,15 @@ class Telegram extends ApiClient {
}
promoteChatMember (chatId, userId, extra) {
return this.callApi('promoteChatMember', Object.assign({ chat_id: chatId, user_id: userId }, extra))
return this.callApi('promoteChatMember', { chat_id: chatId, user_id: userId, ...extra })
}
restrictChatMember (chatId, userId, extra) {
return this.callApi('restrictChatMember', Object.assign({ chat_id: chatId, user_id: userId }, extra))
return this.callApi('restrictChatMember', { chat_id: chatId, user_id: userId, ...extra })
}
setChatAdministratorCustomTitle (chatId, userId, title) {
return this.callApi('setChatAdministratorCustomTitle', { chat_id: chatId, user_id: userId, custom_title: title })
}
exportChatInviteLink (chatId) {
@@ -199,7 +208,7 @@ class Telegram extends ApiClient {
}
setChatPhoto (chatId, photo) {
return this.callApi('setChatPhoto', { chat_id: chatId, photo: photo })
return this.callApi('setChatPhoto', { chat_id: chatId, photo })
}
deleteChatPhoto (chatId) {
@@ -207,15 +216,15 @@ class Telegram extends ApiClient {
}
setChatTitle (chatId, title) {
return this.callApi('setChatTitle', { chat_id: chatId, title: title })
return this.callApi('setChatTitle', { chat_id: chatId, title })
}
setChatDescription (chatId, description) {
return this.callApi('setChatDescription', { chat_id: chatId, description: description })
return this.callApi('setChatDescription', { chat_id: chatId, description })
}
pinChatMessage (chatId, messageId, extra) {
return this.callApi('pinChatMessage', Object.assign({ chat_id: chatId, message_id: messageId }, extra))
return this.callApi('pinChatMessage', { chat_id: chatId, message_id: messageId, ...extra })
}
unpinChatMessage (chatId) {
@@ -230,35 +239,26 @@ class Telegram extends ApiClient {
return this.callApi('unbanChatMember', { chat_id: chatId, user_id: userId })
}
answerCallbackQuery (callbackQueryId, text, url, showAlert, cacheTime) {
return this.callApi('answerCallbackQuery', {
callback_query_id: callbackQueryId,
text: text,
url: url,
show_alert: showAlert,
cache_time: cacheTime
})
}
answerCbQuery (callbackQueryId, text, showAlert, extra) {
return this.callApi('answerCallbackQuery', Object.assign({
return this.callApi('answerCallbackQuery', {
text,
show_alert: showAlert,
callback_query_id: callbackQueryId,
text: text,
show_alert: showAlert
}, extra))
...extra
})
}
answerGameQuery (callbackQueryId, url) {
return this.callApi('answerCallbackQuery', {
callback_query_id: callbackQueryId,
url: url
url,
callback_query_id: callbackQueryId
})
}
answerShippingQuery (shippingQueryId, ok, shippingOptions, errorMessage) {
return this.callApi('answerShippingQuery', {
ok,
shipping_query_id: shippingQueryId,
ok: ok,
shipping_options: shippingOptions,
error_message: errorMessage
})
@@ -266,27 +266,28 @@ class Telegram extends ApiClient {
answerPreCheckoutQuery (preCheckoutQueryId, ok, errorMessage) {
return this.callApi('answerPreCheckoutQuery', {
ok,
pre_checkout_query_id: preCheckoutQueryId,
ok: ok,
error_message: errorMessage
})
}
editMessageText (chatId, messageId, inlineMessageId, text, extra) {
return this.callApi('editMessageText', Object.assign({
return this.callApi('editMessageText', {
text,
chat_id: chatId,
message_id: messageId,
inline_message_id: inlineMessageId,
text: text
}, extra))
...extra
})
}
editMessageCaption (chatId, messageId, inlineMessageId, caption, extra = {}) {
return this.callApi('editMessageCaption', {
caption,
chat_id: chatId,
message_id: messageId,
inline_message_id: inlineMessageId,
caption: caption,
parse_mode: extra.parse_mode,
reply_markup: extra.parse_mode || extra.reply_markup ? extra.reply_markup : extra
})
@@ -297,7 +298,7 @@ class Telegram extends ApiClient {
chat_id: chatId,
message_id: messageId,
inline_message_id: inlineMessageId,
media: Object.assign(media, { parse_mode: extra.parse_mode }),
media: { ...media, parse_mode: extra.parse_mode },
reply_markup: extra.reply_markup ? extra.reply_markup : extra
})
}
@@ -349,8 +350,8 @@ class Telegram extends ApiClient {
return this.callApi('deleteChatStickerSet', { chat_id: chatId })
}
getStickerSet (setName) {
return this.callApi('getStickerSet', { name: setName })
getStickerSet (name) {
return this.callApi('getStickerSet', { name })
}
uploadStickerFile (ownerId, stickerFile) {
@@ -361,30 +362,39 @@ class Telegram extends ApiClient {
}
createNewStickerSet (ownerId, name, title, stickerData) {
return this.callApi('createNewStickerSet', Object.assign({
return this.callApi('createNewStickerSet', {
name,
title,
user_id: ownerId,
name: name,
title: title
}, stickerData))
...stickerData
})
}
addStickerToSet (ownerId, name, stickerData, isMasks) {
return this.callApi('addStickerToSet', Object.assign({
return this.callApi('addStickerToSet', {
name,
user_id: ownerId,
name: name,
is_masks: isMasks
}, stickerData))
is_masks: isMasks,
...stickerData
})
}
setStickerPositionInSet (sticker, position) {
return this.callApi('setStickerPositionInSet', {
sticker: sticker,
position: position
sticker,
position
})
}
deleteStickerFromSet (sticker) {
return this.callApi('deleteStickerFromSet', { sticker: sticker })
return this.callApi('deleteStickerFromSet', { sticker })
}
setPassportDataErrors (userId, errors) {
return this.callApi('setPassportDataErrors', {
user_id: userId,
errors: errors
})
}
sendCopy (chatId, message, extra) {
@@ -395,11 +405,13 @@ class Telegram extends ApiClient {
if (!type) {
throw new Error('Unsupported message type')
}
const opts = Object.assign({ chat_id: chatId }, replicators[type](message), extra)
const opts = {
chat_id: chatId,
...replicators[type](message),
...extra
}
return this.callApi(replicators.copyMethods[type], opts)
}
}
Telegram.prototype.answerCallbackQuery = util.deprecate(Telegram.prototype.answerCallbackQuery, '️⚠️ Telegraf: answerCallbackQuery() is deprecated, use answerCbQuery() instead')
module.exports = Telegram
+38 -28
View File
@@ -5,19 +5,27 @@
"requires": true,
"dependencies": {
"@types/node": {
"version": "12.7.12",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.12.tgz",
"integrity": "sha512-KPYGmfD0/b1eXurQ59fXD1GBzhSQfz6/lKBxkaHX9dKTzjXbK68Zt7yGUxUsCS1jeTy/8aL+d9JEr+S54mpkWQ=="
"version": "13.7.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.0.tgz",
"integrity": "sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ=="
},
"ccxt": {
"version": "1.21.82",
"resolved": "https://registry.npmjs.org/ccxt/-/ccxt-1.21.82.tgz",
"integrity": "sha512-+HX/6WK8BM5c9OwhALl9zzMKvueZfHDXVmfrKNmQ4005hc+BtNuNe47XEs6dAylY+ll7n9JpzaoIZhy6Lipiew=="
"version": "1.22.39",
"resolved": "https://registry.npmjs.org/ccxt/-/ccxt-1.22.39.tgz",
"integrity": "sha512-Vq4BzYS/FwRudPKQ6BQGU3SVntYv7EAQGT+2guf+e7qm45CJMhdoVwR1z89kl42fbK39XMnl8sUnRCwsKPs38A=="
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"requires": {
"ms": "2.1.2"
}
},
"dotenv": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.0.0.tgz",
"integrity": "sha512-30xVGqjLjiUOArT4+M5q9sYdvuR4riM6yK9wMcas9Vbp6zZa+ocC9dp6QoftuhTPhFAiLK/0C5Ni2nou/Bk8lg=="
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
"integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw=="
},
"easy-stack": {
"version": "1.0.0",
@@ -42,6 +50,21 @@
"easy-stack": "1.0.0"
}
},
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
},
"module-alias": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz",
"integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q=="
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node-fetch": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
@@ -63,30 +86,17 @@
"integrity": "sha512-jLYV0DORrzY3xaz/S9ydJL6Iz7essZeAfnAavsJ+zsJGZ1MOnsS52yRjU3uF3pJa/lla7+wisp//fxOwOH8SKQ=="
},
"telegraf": {
"version": "3.32.0",
"resolved": "https://registry.npmjs.org/telegraf/-/telegraf-3.32.0.tgz",
"integrity": "sha512-5ZHiovyuG1rVLygJjaqf57wDt8e1nijAinKXCxN1tyUZ4BcrkZW/z5rVTEXA+KegpFbWxKKv3KnJwUJrKDqD0Q==",
"version": "3.36.0",
"resolved": "https://registry.npmjs.org/telegraf/-/telegraf-3.36.0.tgz",
"integrity": "sha512-9o6AJKRiTm5vMWYI6WpTfBHzu4FMpWBNKxvnMxRds/cbMY9RnsVVjdi8i4bFFlfd+xbi73EbrnI3dybayryICA==",
"requires": {
"@types/node": "12.7.12",
"@types/node": "13.7.0",
"debug": "4.1.1",
"minimist": "1.2.0",
"module-alias": "2.2.2",
"node-fetch": "2.6.0",
"sandwich-stream": "2.0.2",
"telegram-typings": "3.6.1"
},
"dependencies": {
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"requires": {
"ms": "2.1.2"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"telegram-typings": {
+3 -3
View File
@@ -13,9 +13,9 @@
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"ccxt": "^1.21.82",
"dotenv": "^8.0.0",
"ccxt": "^1.22.39",
"dotenv": "^8.2.0",
"node-ipc": "^9.1.1",
"telegraf": "^3.32.0"
"telegraf": "^3.36.0"
}
}
+2
View File
@@ -22,4 +22,6 @@ indicator_bot: "An indicator bot processes data to produce more elaborate datase
trading_bot: "Based on datasets exposed as products by other bots (counting sensors, indicators and even other trading bots), a trading bot applies the trading logic defined on a trading system to, on one side, generate a complete trading simulation (outputting datasets that include trades, the action of strategies, validation of conditions, etc.), and on the other side, manage the execution of orders when on a forward testing or live trading session."
superalgos_protocol: "In conceptual terms, the Superalgos Protocol determines the structure in which the information decribing a trading system is stored and provides guidance on how traders shall create and automate strategies. In practical terms, the protocol results in a file with a specific format capable of holding all the information concerning any number and variety of strategies. In its current early version, the protocol is the description of a JSON object which defines the desired automation."
pending: "balanceAssetA, balanceAssetB, overfitting, supported assets, supported exchanges, supported markets"
+2 -2
View File
@@ -38,7 +38,7 @@ key_instance: "The key instance is a reference to an exchange account key as def
data_storage: "The data storage node controls aspects of what data is to be stored in the corresponding network node."
session-based_data: "Session-based data refers to data that is generated as a consequence of running a session, that is, data the trading bot instance generates while running backtesting, paper trading, forward testing or live trading sessions."
session_based_data: "Session-based data refers to data that is generated as a consequence of running a session, that is, data the trading bot instance generates while running backtesting, paper trading, forward testing or live trading sessions."
session_reference: "A session reference establishes which session is the one which shall store data in the current location."
@@ -48,6 +48,6 @@ data_product: "A data product represents the collection of datasets generated by
dataset: "A data set is a collection of files stored in the designated location, as per the definitions on the referenced data product in the corresponding data mine."
session-independent_data: "Session independent data refers to data generated by sensors and indicators, not related to trading sessions."
session_independent_data: "Session independent data refers to data generated by sensors and indicators, not related to trading sessions."
session: "A session, or trading session, is a specific mode in which the trading bot instance may be run. The trading bot is prepared to run three different types of testing sessions&mdash;backtesting, paper trading, and forward testing&mdash;and the live trading session mode."
+2 -2
View File
@@ -38,7 +38,7 @@ key_instance: "The key instance is a reference to an exchange account key as def
data_storage: "The data storage node controls aspects of what data is to be stored in the corresponding network node."
session-based_data: "Session-based data refers to data that is generated as a consequence of running a session, that is, data the trading bot instance generates while running backtesting, paper trading, forward testing or live trading sessions."
session_based_data: "Session-based data refers to data that is generated as a consequence of running a session, that is, data the trading bot instance generates while running backtesting, paper trading, forward testing or live trading sessions."
session_reference: "A session reference establishes which session is the one which shall store data in the current location."
@@ -48,6 +48,6 @@ data_product: "A data product represents the collection of datasets generated by
dataset: "A data set is a collection of files stored in the designated location, as per the definitions on the referenced data product in the corresponding data mine."
session-independent_data: "Session independent data refers to data generated by sensors and indicators, not related to trading sessions."
session_independent_data: "Session independent data refers to data generated by sensors and indicators, not related to trading sessions."
session: "A session, or trading session, is a specific mode in which the trading bot instance may be run. The trading bot is prepared to run three different types of testing sessions&mdash;backtesting, paper trading, and forward testing&mdash;and the live trading session mode."
+1 -1
View File
@@ -281,7 +281,7 @@ entries:
url: /suite-crypto-ecosystem-hierarchy.html
output: web
- title: Charting Space
- title: Charting space
url: /suite-charting-space-hierarchy.html
output: web
@@ -0,0 +1,100 @@
<!--------------------------------------------- TITLE AND DEFINITION starts -->
{% assign title = "XXXXXXXXXXXXXXXX" %}
{% assign definition = site.data.network.XXXXXXXXXXXXXXXX %}
{% assign preposition = "XXXXXXXXXXXXXXXX" %}
{% assign plural = "s" %}
<!--------------------------------------------- TITLE AND DEFINITION ends -->
{% if include.heading != "" %}
{{include.heading}} {{title}}
{% endif %}
{% if include.icon != "no" %}
{% if include.table == "yes" and include.icon != "no" %}
<table class="definitionTable"><tr><td>
{% endif %}
<img src='images/icons/{{include.icon}}{{ title | downcase | replace: " ", "-" }}.png' />
{% if include.table == "yes" and include.icon != "no" %}
</td><td>
{% endif %}
{% endif %}
{% if include.definition == "bold" %}
<strong>{{ definition }}</strong>
{% else %}
{{ definition }}
{% endif %}
{% if include.table == "yes" and include.icon != "no" %}
</td></tr></table>
{% endif %}
{% if include.more == "yes" and include.content == "more" %}
<details><summary class="nobr">Click to learn more about {{ title | downcase }}{{plural}}
</summary>
{% endif %}
{% if include.content != "no" %}
<!--------------------------------------------- CONTENT starts -->
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<!--------------------------------------------- CONTENT ends -->
{% endif %}
{% if include.more == "yes" and include.content != "more" %}
<details><summary class="nobr">Click to learn more about {{ title | downcase }}{{plural}}
</summary>
{% endif %}
{% if include.adding != "" %}
{{include.adding}} Adding {{preposition}} {{title}}
<!--------------------------------------------- ADDING starts -->
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<!--------------------------------------------- ADDING ends -->
{% endif %}
{% if include.configuring != "" %}
{{include.configuring}} Configuring the {{title}}
<!--------------------------------------------- CONFIGURING starts -->
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<!--------------------------------------------- CONFIGURING ends -->
{% endif %}
{% if include.starting != "" %}
{{include.starting}} Starting {{preposition}} {{title}}
<!--------------------------------------------- STARTING starts -->
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<!--------------------------------------------- STARTING ends -->
{% endif %}
{% if include.more == "yes" %}
</details>
{% endif %}
+100
View File
@@ -0,0 +1,100 @@
<!--------------------------------------------- TITLE AND DEFINITION starts -->
{% assign title = "Data Mining" %}
{% assign definition = site.data.network.data_mining %}
{% assign preposition = "" %}
{% assign plural = "" %}
<!--------------------------------------------- TITLE AND DEFINITION ends -->
{% if include.heading != "" %}
{{include.heading}} {{title}}
{% endif %}
{% if include.icon != "no" %}
{% if include.table == "yes" and include.icon != "no" %}
<table class="definitionTable"><tr><td>
{% endif %}
<img src='images/icons/{{include.icon}}{{ title | downcase | replace: " ", "-" }}.png' />
{% if include.table == "yes" and include.icon != "no" %}
</td><td>
{% endif %}
{% endif %}
{% if include.definition == "bold" %}
<strong>{{ definition }}</strong>
{% else %}
{{ definition }}
{% endif %}
{% if include.table == "yes" and include.icon != "no" %}
</td></tr></table>
{% endif %}
{% if include.more == "yes" and include.content == "more" %}
<details><summary class="nobr">Click to learn more about {{ title | downcase }}{{plural}}
</summary>
{% endif %}
{% if include.content != "no" %}
<!--------------------------------------------- CONTENT starts -->
Users may have access to several data mines. For organizational purposes, it is recommended each data mine has its task manager. However, the system allows any form of organization.
<!--------------------------------------------- CONTENT ends -->
{% endif %}
{% if include.more == "yes" and include.content != "more" %}
<details><summary class="nobr">Click to learn more about {{ title | downcase }}{{plural}}
</summary>
{% endif %}
{% if include.adding != "" %}
{{include.adding}} Adding {{preposition}} {{title}}
<!--------------------------------------------- ADDING starts -->
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<!--------------------------------------------- ADDING ends -->
{% endif %}
{% if include.configuring != "" %}
{{include.configuring}} Configuring the {{title}}
<!--------------------------------------------- CONFIGURING starts -->
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<!--------------------------------------------- CONFIGURING ends -->
{% endif %}
{% if include.starting != "" %}
{{include.starting}} Starting {{preposition}} {{title}}
<!--------------------------------------------- STARTING starts -->
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<!--------------------------------------------- STARTING ends -->
{% endif %}
{% if include.more == "yes" %}
</details>
{% endif %}
+102
View File
@@ -0,0 +1,102 @@
<!--------------------------------------------- TITLE AND DEFINITION starts -->
{% assign title = "Data Product" %}
{% assign definition = site.data.network.data_product %}
{% assign preposition = "a" %}
{% assign plural = "s" %}
<!--------------------------------------------- TITLE AND DEFINITION ends -->
{% if include.heading != "" %}
{{include.heading}} {{title}}
{% endif %}
{% if include.icon != "no" %}
{% if include.table == "yes" and include.icon != "no" %}
<table class="definitionTable"><tr><td>
{% endif %}
<img src='images/icons/{{include.icon}}{{ title | downcase | replace: " ", "-" }}.png' />
{% if include.table == "yes" and include.icon != "no" %}
</td><td>
{% endif %}
{% endif %}
{% if include.definition == "bold" %}
<strong>{{ definition }}</strong>
{% else %}
{{ definition }}
{% endif %}
{% if include.table == "yes" and include.icon != "no" %}
</td></tr></table>
{% endif %}
{% if include.more == "yes" and include.content == "more" %}
<details><summary class="nobr">Click to learn more about {{ title | downcase }}{{plural}}
</summary>
{% endif %}
{% if include.content != "no" %}
<!--------------------------------------------- CONTENT starts -->
A data product node must reference a product definition in the corresponding data mine.
<!--------------------------------------------- CONTENT ends -->
{% endif %}
{% if include.more == "yes" and include.content != "more" %}
<details><summary class="nobr">Click to learn more about {{ title | downcase }}{{plural}}
</summary>
{% endif %}
{% if include.adding != "" %}
{{include.adding}} Adding {{preposition}} {{title}}
<!--------------------------------------------- ADDING starts -->
To add a data product, select *Add Data Product* on the network node menu.
{% include note.html content="Remember to establish a reference with a product definition of the corresponding bot in the corresponding data mine." %}
<!--------------------------------------------- ADDING ends -->
{% endif %}
{% if include.configuring != "" %}
{{include.configuring}} Configuring the {{title}}
<!--------------------------------------------- CONFIGURING starts -->
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<!--------------------------------------------- CONFIGURING ends -->
{% endif %}
{% if include.starting != "" %}
{{include.starting}} Starting {{preposition}} {{title}}
<!--------------------------------------------- STARTING starts -->
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<!--------------------------------------------- STARTING ends -->
{% endif %}
{% if include.more == "yes" %}
</details>
{% endif %}
+104
View File
@@ -0,0 +1,104 @@
<!--------------------------------------------- TITLE AND DEFINITION starts -->
{% assign title = "Data Storage" %}
{% assign definition = site.data.network.data_storage %}
{% assign preposition = "a" %}
{% assign plural = "s" %}
<!--------------------------------------------- TITLE AND DEFINITION ends -->
{% if include.heading != "" %}
{{include.heading}} {{title}}
{% endif %}
{% if include.icon != "no" %}
{% if include.table == "yes" and include.icon != "no" %}
<table class="definitionTable"><tr><td>
{% endif %}
<img src='images/icons/{{include.icon}}{{ title | downcase | replace: " ", "-" }}.png' />
{% if include.table == "yes" and include.icon != "no" %}
</td><td>
{% endif %}
{% endif %}
{% if include.definition == "bold" %}
<strong>{{ definition }}</strong>
{% else %}
{{ definition }}
{% endif %}
{% if include.table == "yes" and include.icon != "no" %}
</td></tr></table>
{% endif %}
{% if include.more == "yes" and include.content == "more" %}
<details><summary class="nobr">Click to learn more about {{ title | downcase }}{{plural}}
</summary>
{% endif %}
{% if include.content != "no" %}
<!--------------------------------------------- CONTENT starts -->
Data products generated by the bot instances you run need to be stored somewhere&mdash;specifically. The data storage node and its chain of offspring determine that the data is to be stored in the corresponding node.
{% include note.html content="At this point, the only node in which you may store data is your local *My Computer* node, however, in the future you will be able to store data, or even run bots, on remote machines that you will control from within your local deployment of the system." %}
<!--------------------------------------------- CONTENT ends -->
{% endif %}
{% if include.more == "yes" and include.content != "more" %}
<details><summary class="nobr">Click to learn more about {{ title | downcase }}{{plural}}
</summary>
{% endif %}
{% if include.adding != "" %}
{{include.adding}} Adding {{preposition}} {{title}}
<!--------------------------------------------- ADDING starts -->
To add a data storage, select *Add Data Storage* on the network node menu.
{% include note.html content="Only one data storage may exist on each network node." %}
<!--------------------------------------------- ADDING ends -->
{% endif %}
{% if include.configuring != "" %}
{{include.configuring}} Configuring the {{title}}
<!--------------------------------------------- CONFIGURING starts -->
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<!--------------------------------------------- CONFIGURING ends -->
{% endif %}
{% if include.starting != "" %}
{{include.starting}} Starting {{preposition}} {{title}}
<!--------------------------------------------- STARTING starts -->
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<!--------------------------------------------- STARTING ends -->
{% endif %}
{% if include.more == "yes" %}
</details>
{% endif %}
Loaded 100 of 131 files, more files were not shown because too many files have changed in this diff. Show more