这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bfx-report",
"version": "4.5.1",
"version": "4.6.0",
"description": "Reporting tool",
"main": "worker.js",
"license": "Apache-2.0",
Expand Down
30 changes: 25 additions & 5 deletions test/1-api.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,22 +239,42 @@ describe('API', () => {
assert.isArray(res.body.result.pairs)
assert.isArray(res.body.result.currencies)
assert.isArray(res.body.result.inactiveSymbols)
assert.isArray(res.body.result.mapSymbols)
assert.isArray(res.body.result.inactiveCurrencies)
assert.isArray(res.body.result.marginCurrencyList)
assert.lengthOf(res.body.result.pairs, 13)
assert.lengthOf(res.body.result.currencies, 11)
assert.lengthOf(res.body.result.inactiveSymbols, 2)
assert.lengthOf(res.body.result.mapSymbols, 3)
assert.lengthOf(res.body.result.inactiveCurrencies, 2)
assert.lengthOf(res.body.result.marginCurrencyList, 4)

res.body.result.mapSymbols.forEach(item => {
assert.lengthOf(item, 2)
})
res.body.result.pairs.forEach(item => {
res.body.result.pairs.forEach((item) => {
assert.isString(item)
})
res.body.result.currencies.forEach(item => {
res.body.result.currencies.forEach((item) => {
assert.isObject(item)
assert.isString(item.id)
assert.isString(item.name)
assert.isBoolean(item.active)
assert.isBoolean(item.isInPair)
assert.isBoolean(item.isFunding)
})
res.body.result.inactiveSymbols.forEach((item) => {
assert.isString(item)
})
res.body.result.mapSymbols.forEach((item) => {
assert.lengthOf(item, 2)

item.forEach((item) => {
assert.isString(item)
})
})
res.body.result.inactiveCurrencies.forEach((item) => {
assert.isString(item)
})
res.body.result.marginCurrencyList.forEach((item) => {
assert.isString(item)
})
})

Expand Down
1 change: 1 addition & 0 deletions test/helpers/helpers.mock-rest-v2.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ const getMockDataOpts = () => ({
symbols: null,
map_symbols: null,
inactive_currencies: null,
margin_currencies: null,
inactive_symbols: null,
futures: null,
currencies: null,
Expand Down
9 changes: 9 additions & 0 deletions test/helpers/mock-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ module.exports = new Map([
'DDD'
]]
],
[
'margin_currencies',
[[
'BTC',
'ETH',
'LEO',
'USD'
]]
],
[
'inactive_symbols',
[[
Expand Down
4 changes: 3 additions & 1 deletion workers/loc.api/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
const getREST = require('./get-rest')
const {
prepareResponse,
prepareApiResponse
prepareApiResponse,
prepareSymbolResponse
} = require('./prepare-response')
const checkParams = require('./check-params')
const {
Expand Down Expand Up @@ -88,6 +89,7 @@ module.exports = {
checkTimeLimit,
prepareResponse,
prepareApiResponse,
prepareSymbolResponse,
getCsvArgs,
getMethodLimit,
checkJobAndGetUserData,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,30 @@ const OMITTING_FIELDS = [
'emptyFill'
]

const _omitFields = (obj) => {
const _omitFields = (obj, opts) => {
const newObj = omit(obj, OMITTING_FIELDS)
newObj._isDataFromApiV2 = true

if (!opts?.isNotDataFromApiV2) {
newObj._isDataFromApiV2 = true
}

return newObj
}

module.exports = (res) => {
module.exports = (res, opts) => {
if (
Array.isArray(res) &&
res.length > 0 &&
res.every((item) => (item && typeof item === 'object'))
) {
return res.map((item) => _omitFields(item))
return res.map((item) => _omitFields(item, opts))
}
if (
res &&
typeof res === 'object' &&
Object.keys(res).length > 0
) {
return _omitFields(res)
return _omitFields(res, opts)
}

return res
Expand Down
5 changes: 4 additions & 1 deletion workers/loc.api/helpers/prepare-response/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ const checkParams = require('../check-params')
const checkFilterParams = require('../check-filter-params')
const normalizeFilterParams = require('../normalize-filter-params')

const prepareSymbolResponse = require('./prepare-symbol-response')

const {
getParamsSchemaName,
omitPrivateModelFields,
Expand Down Expand Up @@ -205,5 +207,6 @@ const prepareApiResponse = (

module.exports = {
prepareResponse,
prepareApiResponse
prepareApiResponse,
prepareSymbolResponse
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
'use strict'

const {
omitPrivateModelFields
} = require('./helpers')

const _isInPair = (symbol, pairs) => {
if (
!symbol ||
!Array.isArray(pairs) ||
pairs.length === 0
) {
return false
}

return pairs.some((pair) => {
const [firstSymb, lastSymb] = _splitPair(pair)

return (
firstSymb === symbol ||
lastSymb === symbol
)
})
}

const _splitPair = (pair) => {
if (
!pair ||
typeof pair !== 'string' ||
pair.length < 6
) {
return [pair]
}
if (pair.length === 6) {
return [pair.slice(0, -3), pair.slice(-3)]
}
if (/.+[:].+/.test(pair)) {
return pair.split(':')
}

return [pair]
}

module.exports = (args) => {
const {
symbols,
futures,
currencies: rawCurrencies,
inactiveSymbols,
mapSymbols: rawMapSymbols,
inactiveCurrencies,
marginCurrencyList
} = args ?? {}

// To cover DB response of the framework mode
const isMapSymbolsFromDb = (
Array.isArray(rawMapSymbols) &&
rawMapSymbols[0]?.key &&
rawMapSymbols[0]?.value
)
const mapSymbols = isMapSymbolsFromDb
? rawMapSymbols.map((map) => [map?.key, map?.value])
: rawMapSymbols
const pairs = [...symbols, ...futures]
const currencies = []

for (const currencie of rawCurrencies) {
const { id } = currencie ?? {}

if (
!id ||
typeof id !== 'string'
) {
continue
}

const _currencie = omitPrivateModelFields(
currencie,
{ isNotDataFromApiV2: true }
)

_currencie.active = inactiveCurrencies.every((ccy) => ccy !== id)
_currencie.isInPair = _isInPair(id, pairs)
_currencie.isFunding = marginCurrencyList.some((ccy) => ccy === id)

currencies.push(_currencie)
}

return {
pairs,
currencies,
inactiveSymbols,
mapSymbols,
inactiveCurrencies,
marginCurrencyList
}
}
23 changes: 16 additions & 7 deletions workers/loc.api/responder/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const JSON_RPC_VERSION = '2.0'
const _isHtml = (res) => (_htmlRegExp.test(res))

const _findHtmlTitle = (res) => (
res?.match(_htmlTitleRegExp).groups?.body ?? 'HTML title not found'
res?.match(_htmlTitleRegExp).groups?.body ?? null
)

const _getBfxApiErrorMetadata = (err) => {
Expand All @@ -35,13 +35,13 @@ const _getBfxApiErrorMetadata = (err) => {
const isHtml = _isHtml(err.response)
const body = isHtml
? _findHtmlTitle(err.response)
: err.response ?? 'Response is not abailable'
: err.response ?? null

return {
bfxApiStatus: err.status,
bfxApiStatusText: err.statustext ?? 'Status text is not abailable',
bfxApiRawBodyCode: err.code ?? 'Code is not abailable',
isBfxApiRawBodyResponseHtml: isHtml ? 'Yes' : 'No',
bfxApiStatusText: err.statustext ?? null,
bfxApiRawBodyCode: err.code ?? null,
isBfxApiRawBodyResponseHtml: isHtml,
bfxApiRawBodyResponse: body
}
}
Expand Down Expand Up @@ -148,11 +148,20 @@ const _getErrorMetadata = (args, err) => {
_addStatusMessageToErrorMessage(errWithMetadata)
const {
statusCode: code = 500,
statusMessage: message = 'Internal Server Error',
statusMessage = 'Internal Server Error',
data = null
} = errWithMetadata

const bfxApiErrorMessage = _getBfxApiErrorMetadata(err)
const bfxApiStatusText = bfxApiErrorMessage?.bfxApiStatusText
? `: ${bfxApiErrorMessage?.bfxApiStatusText}`
: ''
const bfxApiRawBodyResponse = bfxApiErrorMessage?.bfxApiRawBodyResponse
? `: ${bfxApiErrorMessage?.bfxApiRawBodyResponse}`
: ''
const message = bfxApiErrorMessage
? `${statusMessage}: BFX API Error${bfxApiStatusText}${bfxApiRawBodyResponse}`
: statusMessage
const extendedData = bfxApiErrorMessage
? {
bfxApiErrorMessage,
Expand All @@ -164,7 +173,7 @@ const _getErrorMetadata = (args, err) => {
errWithMetadata,
{
statusCode: code,
statusMessage: message,
statusMessage,
data: extendedData
}
)
Expand Down
28 changes: 20 additions & 8 deletions workers/loc.api/service.report.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ const {
accountCache,
getTimezoneConf,
filterModels,
parsePositionsAuditId
parsePositionsAuditId,
prepareSymbolResponse
} = require('./helpers')
const {
omitPrivateModelFields
Expand Down Expand Up @@ -99,6 +100,14 @@ class ReportService extends Api {
return Array.isArray(res) ? res : []
}

async _getMarginCurrencyList () {
const [res] = await this._getConf({
keys: 'pub:list:currency:margin'
})

return Array.isArray(res) ? res : []
}

_getWeightedAveragesReportFromApi (args) {
const { auth, params } = args ?? {}

Expand Down Expand Up @@ -206,24 +215,27 @@ class ReportService extends Api {
currencies,
inactiveSymbols,
mapSymbols,
inactiveCurrencies
inactiveCurrencies,
marginCurrencyList
] = await Promise.all([
this._getSymbols(),
this._getFutures(),
this._getCurrencies(),
this._getInactiveSymbols(),
this._getMapSymbols(),
this._getInactiveCurrencies()
this._getInactiveCurrencies(),
this._getMarginCurrencyList()
])

const pairs = [...symbols, ...futures]
const res = {
pairs,
const res = prepareSymbolResponse({
symbols,
futures,
currencies,
inactiveSymbols,
mapSymbols,
inactiveCurrencies
}
inactiveCurrencies,
marginCurrencyList
})

accountCache.set('symbols', res)

Expand Down