IPC removed, replaced by WS
This commit is contained in:
1 parent
ba4217fb24
commit
656c193511
503 files changed
+28128
-34498
No files matched your search
+2
-2
@@ -26,9 +26,9 @@ function cleanupOldTags () {
|
||||
|
||||
const tagsByMajorMinor = values (groupBy (tags, 'key')).sort ((a, b) => a[0].key - b[0].key)
|
||||
|
||||
// Preserve all tags for first 3 minor versions
|
||||
// Preserve all tags for first 5 minor versions
|
||||
|
||||
for (let i = 0; i < 3; i++) {
|
||||
for (let i = 0; i < 5; i++) {
|
||||
|
||||
const tags = tagsByMajorMinor.pop ()
|
||||
|
||||
|
||||
+175
-112
@@ -93,49 +93,51 @@ function createExchanges (ids) {
|
||||
// ----------------------------------------------------------------------------
|
||||
// TODO: REWRITE THIS ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
|
||||
|
||||
function exportSupportedAndCertifiedExchanges (exchanges, wikiPath) {
|
||||
function exportSupportedAndCertifiedExchanges (exchanges, { allExchangesPaths, certifiedExchangesPaths, exchangesByCountriesPaths, proExchangesPaths }) {
|
||||
|
||||
// ............................................................................
|
||||
// markup constants and helper functions
|
||||
|
||||
const countryName = (code) => countries[code] || code
|
||||
|
||||
const ccxtCertifiedBadge = '[](https://github.com/ccxt/ccxt/wiki/Certification)'
|
||||
const ccxtCertifiedBadge = '[](https://github.com/ccxt/ccxt/wiki/Certification)'
|
||||
const ccxtProBadge = '[](https://ccxt.pro)'
|
||||
const logoHeading = ' '.repeat (7) + 'logo' + ' '.repeat (7)
|
||||
const tableHeadings = [ logoHeading, 'id', 'name', 'ver', 'doc', 'certified', ]
|
||||
const exchangesByCountryHeading = [ 'country / region', ... tableHeadings ]
|
||||
const tableHeadings = [ logoHeading, 'id', 'name', 'ver', 'doc', 'certified', 'pro' ]
|
||||
const exchangesByCountryHeading = [ 'country / region', ... tableHeadings.slice (0, 5) ]
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// list all supported exchanges
|
||||
|
||||
const exchangesNotListedInDocs = []
|
||||
const exchangesNotListedInDocs = [ 'hitbtc2' ]
|
||||
|
||||
let tableData = values (exchanges)
|
||||
.filter (exchange => !exchangesNotListedInDocs.includes (exchange.id))
|
||||
.map (exchange => {
|
||||
let logo = exchange.urls['logo']
|
||||
let website = Array.isArray (exchange.urls.www) ? exchange.urls.www[0] : exchange.urls.www
|
||||
let url = exchange.urls.referral || website
|
||||
let countries = Array.isArray (exchange.countries) ? exchange.countries.map (countryName).join (', ') : countryName (exchange.countries)
|
||||
let doc = Array.isArray (exchange.urls.doc) ? exchange.urls.doc[0] : exchange.urls.doc
|
||||
let version = exchange.version ? exchange.version : '\*'
|
||||
let matches = version.match (/[^0-9]*([0-9].*)/)
|
||||
if (matches) {
|
||||
version = matches[1];
|
||||
}
|
||||
return [
|
||||
'[](' + url + ')',
|
||||
exchange.id,
|
||||
'[' + exchange.name + '](' + url + ')',
|
||||
version,
|
||||
'[API](' + doc + ')',
|
||||
exchange.certified ? ccxtCertifiedBadge : '',
|
||||
countries,
|
||||
]
|
||||
})
|
||||
function makeTableData (exchanges) {
|
||||
return (
|
||||
values (exchanges)
|
||||
.filter (exchange => !exchangesNotListedInDocs.includes (exchange.id))
|
||||
.map (exchange => {
|
||||
let logo = exchange.urls['logo']
|
||||
let website = Array.isArray (exchange.urls.www) ? exchange.urls.www[0] : exchange.urls.www
|
||||
let url = exchange.urls.referral || website
|
||||
let doc = Array.isArray (exchange.urls.doc) ? exchange.urls.doc[0] : exchange.urls.doc
|
||||
let version = exchange.version ? exchange.version : '\*'
|
||||
let matches = version.match (/[^0-9]*([0-9].*)/)
|
||||
if (matches) {
|
||||
version = matches[1];
|
||||
}
|
||||
return [
|
||||
'[](' + url + ')',
|
||||
exchange.id,
|
||||
'[' + exchange.name + '](' + url + ')',
|
||||
version,
|
||||
'[API](' + doc + ')',
|
||||
exchange.certified ? ccxtCertifiedBadge : '',
|
||||
exchange.pro ? ccxtProBadge : '',
|
||||
]
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
// prepend the table header
|
||||
tableData.splice (0, 0, tableHeadings)
|
||||
|
||||
function makeTable (jsonArray) {
|
||||
let table = asTable.configure ({ 'delimiter': ' | ' }) (jsonArray)
|
||||
@@ -148,88 +150,128 @@ function exportSupportedAndCertifiedExchanges (exchanges, wikiPath) {
|
||||
return lines.map (line => '|' + line + '|').join ("\n")
|
||||
}
|
||||
|
||||
const exchangesTable = makeTable (tableData)
|
||||
const numExchanges = keys (exchanges).length
|
||||
const beginning = "The ccxt library currently supports the following "
|
||||
const ending = " cryptocurrency exchange markets and trading APIs:\n\n"
|
||||
const totalString = beginning + numExchanges + ending
|
||||
const allExchanges = totalString + exchangesTable + "$1"
|
||||
const allExchangesRegex = new RegExp ("[^\n]+[\n]{2}\\|[^`]+\\|([\n][\n]|[\n]$|$)", 'm')
|
||||
logExportExchanges ('README.md', allExchangesRegex, allExchanges)
|
||||
logExportExchanges (wikiPath + '/Manual.md', allExchangesRegex, allExchanges)
|
||||
logExportExchanges (wikiPath + '/Exchange-Markets.md', allExchangesRegex, allExchanges)
|
||||
if (allExchangesPaths) {
|
||||
|
||||
const certifiedFieldIndex = tableHeadings.indexOf ('certified')
|
||||
const certified = tableData.filter ((x) => x[certifiedFieldIndex] !== '' )
|
||||
const certifiedExchangesRegex = new RegExp ("^(## Certified Cryptocurrency Exchanges\n{3})(?:\\|.+\\|$\n)+", 'm')
|
||||
const certifiedExchangesTable = makeTable (certified)
|
||||
const certifiedExchanges = '$1' + certifiedExchangesTable + "\n"
|
||||
logExportExchanges ('README.md', certifiedExchangesRegex, certifiedExchanges)
|
||||
const tableData = makeTableData (exchanges)
|
||||
const numExchanges = tableData.length
|
||||
// prepend the table header
|
||||
tableData.splice (0, 0, tableHeadings)
|
||||
const exchangesTable = makeTable (tableData)
|
||||
const beginning = "The CCXT library currently supports the following "
|
||||
const ending = " cryptocurrency exchange markets and trading APIs:\n\n"
|
||||
const totalString = beginning + numExchanges + ending
|
||||
const allExchanges = totalString + exchangesTable + "$1"
|
||||
const allExchangesRegex = new RegExp ("[^\n]+[\n]{2}\\|[^`]+\\|([\n][\n]|[\n]$|$)", 'm')
|
||||
|
||||
for (const path of allExchangesPaths) {
|
||||
logExportExchanges (path, allExchangesRegex, allExchanges)
|
||||
}
|
||||
|
||||
let exchangesByCountries = []
|
||||
keys (countries).forEach (code => {
|
||||
let country = countries[code]
|
||||
let result = []
|
||||
keys (exchanges).forEach (id => {
|
||||
let exchange = exchanges[id]
|
||||
let logo = exchange.urls['logo']
|
||||
let website = Array.isArray (exchange.urls.www) ? exchange.urls.www[0] : exchange.urls.www
|
||||
let url = exchange.urls.referral || website
|
||||
let doc = Array.isArray (exchange.urls.doc) ? exchange.urls.doc[0] : exchange.urls.doc
|
||||
let version = exchange.version ? exchange.version : '\*'
|
||||
let matches = version.match (/[^0-9]*([0-9].*)/)
|
||||
if (matches)
|
||||
version = matches[1];
|
||||
let shouldInclude = false
|
||||
if (Array.isArray (exchange.countries)) {
|
||||
if (exchange.countries.indexOf (code) > -1)
|
||||
shouldInclude = true
|
||||
// logExportExchanges ('README.md', allExchangesRegex, allExchanges)
|
||||
// logExportExchanges (wikiPath + '/Manual.md', allExchangesRegex, allExchanges)
|
||||
// logExportExchanges (wikiPath + '/Exchange-Markets.md', allExchangesRegex, allExchanges)
|
||||
}
|
||||
|
||||
if (proExchangesPaths) {
|
||||
const pro = values (exchanges).filter (exchange => exchange.pro)
|
||||
const tableData = makeTableData (pro)
|
||||
const numExchanges = tableData.length
|
||||
// prepend the table header
|
||||
tableData.splice (0, 0, tableHeadings)
|
||||
const exchangesTable = makeTable (tableData)
|
||||
const beginning = "The CCXT Pro library currently supports the following "
|
||||
const ending = " cryptocurrency exchange markets and WebSocket trading APIs:\n\n"
|
||||
const totalString = beginning + numExchanges + ending
|
||||
const proExchanges = totalString + exchangesTable + "$1"
|
||||
const proExchangesRegex = new RegExp ("[^\n]+[\n]{2}\\|[^`]+\\|([\n][\n]|[\n]$|$)", 'm')
|
||||
|
||||
for (const path of proExchangesPaths) {
|
||||
logExportExchanges (path, proExchangesRegex, proExchanges)
|
||||
}
|
||||
}
|
||||
|
||||
if (certifiedExchangesPaths) {
|
||||
const certified = values (exchanges).filter (exchange => exchange.certified)
|
||||
const tableData = makeTableData (certified)
|
||||
// prepend the table header
|
||||
tableData.splice (0, 0, tableHeadings)
|
||||
const certifiedExchangesRegex = new RegExp ("^(## Certified Cryptocurrency Exchanges\n{3})(?:\\|.+\\|$\n)+", 'm')
|
||||
const certifiedExchangesTable = makeTable (tableData)
|
||||
const certifiedExchanges = '$1' + certifiedExchangesTable + "\n"
|
||||
|
||||
for (const path of certifiedExchangesPaths) {
|
||||
logExportExchanges (path, certifiedExchangesRegex, certifiedExchanges)
|
||||
}
|
||||
|
||||
// logExportExchanges ('README.md', certifiedExchangesRegex, certifiedExchanges)
|
||||
}
|
||||
|
||||
if (exchangesByCountriesPaths) {
|
||||
let exchangesByCountries = []
|
||||
keys (countries).forEach (code => {
|
||||
let country = countries[code]
|
||||
let result = []
|
||||
keys (exchanges).forEach (id => {
|
||||
let exchange = exchanges[id]
|
||||
let logo = exchange.urls['logo']
|
||||
let website = Array.isArray (exchange.urls.www) ? exchange.urls.www[0] : exchange.urls.www
|
||||
let url = exchange.urls.referral || website
|
||||
let doc = Array.isArray (exchange.urls.doc) ? exchange.urls.doc[0] : exchange.urls.doc
|
||||
let version = exchange.version ? exchange.version : '\*'
|
||||
let matches = version.match (/[^0-9]*([0-9].*)/)
|
||||
if (matches)
|
||||
version = matches[1];
|
||||
let shouldInclude = false
|
||||
if (Array.isArray (exchange.countries)) {
|
||||
if (exchange.countries.indexOf (code) > -1)
|
||||
shouldInclude = true
|
||||
} else {
|
||||
if (code == exchange.countries)
|
||||
shouldInclude = true
|
||||
}
|
||||
if (shouldInclude) {
|
||||
let entry = [
|
||||
country,
|
||||
'[](' + url + ')',
|
||||
exchange.id,
|
||||
'[' + exchange.name + '](' + url + ')',
|
||||
version,
|
||||
'[API](' + doc + ')',
|
||||
// doesn't fit in width
|
||||
// exchange.certified ? ccxtCertifiedBadge : '',
|
||||
]
|
||||
result.push (entry)
|
||||
}
|
||||
})
|
||||
exchangesByCountries = exchangesByCountries.concat (result)
|
||||
});
|
||||
|
||||
const countryKeyIndex = exchangesByCountryHeading.indexOf ('country / region')
|
||||
exchangesByCountries = exchangesByCountries.sort ((a, b) => {
|
||||
const countryA = a[countryKeyIndex].toLowerCase ()
|
||||
const countryB = b[countryKeyIndex].toLowerCase ()
|
||||
if (countryA > countryB) {
|
||||
return 1
|
||||
} else if (countryA < countryB) {
|
||||
return -1;
|
||||
} else {
|
||||
if (code == exchange.countries)
|
||||
shouldInclude = true
|
||||
}
|
||||
if (shouldInclude) {
|
||||
let entry = [
|
||||
country,
|
||||
'[](' + url + ')',
|
||||
exchange.id,
|
||||
'[' + exchange.name + '](' + url + ')',
|
||||
version,
|
||||
'[API](' + doc + ')',
|
||||
// doesn't fit in width
|
||||
// exchange.certified ? ccxtCertifiedBadge : '',
|
||||
]
|
||||
result.push (entry)
|
||||
if (a['id'] > b['id'])
|
||||
return 1;
|
||||
else if (a['id'] < b['id'])
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
})
|
||||
exchangesByCountries = exchangesByCountries.concat (result)
|
||||
});
|
||||
|
||||
let countryKeyIndex = exchangesByCountryHeading.indexOf ('country / region')
|
||||
exchangesByCountries = exchangesByCountries.sort ((a, b) => {
|
||||
let countryA = a[countryKeyIndex].toLowerCase ()
|
||||
let countryB = b[countryKeyIndex].toLowerCase ()
|
||||
if (countryA > countryB) {
|
||||
return 1
|
||||
} else if (countryA < countryB) {
|
||||
return -1;
|
||||
} else {
|
||||
if (a['id'] > b['id'])
|
||||
return 1;
|
||||
else if (a['id'] < b['id'])
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
exchangesByCountries.splice (0, 0, exchangesByCountryHeading)
|
||||
const lines = makeTable (exchangesByCountries)
|
||||
const result = "# Exchanges By Country\n\nThe ccxt library currently supports the following cryptocurrency exchange markets and trading APIs:\n\n" + lines + "\n\n"
|
||||
for (const path of exchangesByCountriesPaths) {
|
||||
fs.truncateSync (path)
|
||||
fs.writeFileSync (path, result)
|
||||
}
|
||||
})
|
||||
|
||||
exchangesByCountries.splice (0, 0, exchangesByCountryHeading)
|
||||
let lines = makeTable (exchangesByCountries)
|
||||
let result = "# Exchanges By Country\n\nThe ccxt library currently supports the following cryptocurrency exchange markets and trading APIs:\n\n" + lines + "\n\n"
|
||||
let filename = wikiPath + '/Exchange-Markets-By-Country.md'
|
||||
fs.truncateSync (filename)
|
||||
fs.writeFileSync (filename, result)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: REWRITE THIS ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
|
||||
@@ -237,7 +279,9 @@ function exportSupportedAndCertifiedExchanges (exchanges, wikiPath) {
|
||||
|
||||
function exportExchangeIdsToExchangesJson (exchanges) {
|
||||
log.bright ('Exporting exchange ids to'.cyan, 'exchanges.json'.yellow)
|
||||
fs.writeFileSync ('exchanges.json', JSON.stringify ({ ids: keys (exchanges) }, null, 4))
|
||||
const ids = keys (exchanges)
|
||||
console.log (ids)
|
||||
fs.writeFileSync ('exchanges.json', JSON.stringify ({ ids }, null, 4))
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -252,6 +296,9 @@ function exportWikiToGitHub (wikiPath, gitWikiPath) {
|
||||
'Manual.md': 'Manual.md',
|
||||
'Exchange-Markets.md': 'Exchange-Markets.md',
|
||||
'Exchange-Markets-By-Country.md': 'Exchange-Markets-By-Country.md',
|
||||
'ccxt.pro.md': 'ccxt.pro.md',
|
||||
'ccxt.pro.install.md': 'ccxt.pro.install.md',
|
||||
'ccxt.pro.manual.md': 'ccxt.pro.manual.md',
|
||||
}
|
||||
|
||||
for (const [ sourceFile, destinationFile ] of entries (ccxtWikiFiles)) {
|
||||
@@ -281,18 +328,13 @@ function exportKeywordsToPackageJson (exchanges) {
|
||||
}
|
||||
|
||||
packageJSON.keywords = [...keywords]
|
||||
fs.writeFileSync ('./package.json', JSON.stringify (packageJSON, null, 2))
|
||||
fs.writeFileSync ('./package.json', JSON.stringify (packageJSON, null, 2) + "\n")
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
function exportEverything () {
|
||||
|
||||
const wikiPath = 'wiki'
|
||||
, gitWikiPath = 'build/ccxt.wiki'
|
||||
|
||||
cloneGitHubWiki (gitWikiPath)
|
||||
|
||||
const ids = getIncludedExchangeIds ()
|
||||
|
||||
const replacements = [
|
||||
@@ -333,7 +375,28 @@ function exportEverything () {
|
||||
// strategically placed exactly here (we can require it AFTER the export)
|
||||
const exchanges = createExchanges (ids)
|
||||
|
||||
exportSupportedAndCertifiedExchanges (exchanges, wikiPath)
|
||||
const wikiPath = 'wiki'
|
||||
, gitWikiPath = 'build/ccxt.wiki'
|
||||
|
||||
cloneGitHubWiki (gitWikiPath)
|
||||
|
||||
exportSupportedAndCertifiedExchanges (exchanges, {
|
||||
allExchangesPaths: [
|
||||
'README.md',
|
||||
wikiPath + '/Manual.md',
|
||||
wikiPath + '/Exchange-Markets.md'
|
||||
],
|
||||
certifiedExchangesPaths: [
|
||||
'README.md',
|
||||
],
|
||||
exchangesByCountriesPaths: [
|
||||
wikiPath + '/Exchange-Markets-By-Country.md'
|
||||
],
|
||||
proExchangesPaths: [
|
||||
wikiPath + '/ccxt.pro.manual.md',
|
||||
],
|
||||
})
|
||||
|
||||
exportExchangeIdsToExchangesJson (exchanges)
|
||||
exportWikiToGitHub (wikiPath, gitWikiPath)
|
||||
exportKeywordsToPackageJson (exchanges)
|
||||
|
||||
+155
-38
@@ -5,16 +5,23 @@
|
||||
"use strict";
|
||||
|
||||
const fs = require ('fs')
|
||||
, log = require ('ololog')
|
||||
, log = require ('ololog').unlimited
|
||||
, _ = require ('ansicolor').nice
|
||||
, errors = require ('../js/base/errors.js')
|
||||
, { unCamelCase, precisionConstants, safeString } = require ('../js/base/functions.js')
|
||||
, functions = require ('../js/base/functions.js')
|
||||
, {
|
||||
unCamelCase,
|
||||
precisionConstants,
|
||||
safeString,
|
||||
unique,
|
||||
} = functions
|
||||
, { basename } = require ('path')
|
||||
, {
|
||||
createFolderRecursively,
|
||||
replaceInFile,
|
||||
overwriteFile,
|
||||
} = require ('./fs.js')
|
||||
, Exchange = require ('../js/base/Exchange.js')
|
||||
|
||||
class Transpiler {
|
||||
|
||||
@@ -60,6 +67,7 @@ class Transpiler {
|
||||
[ /\.parseTrades\s/g, '.parse_trades'],
|
||||
[ /\.parseTrade\s/g, '.parse_trade'],
|
||||
[ /\.parseTradingViewOHLCV\s/g, '.parse_trading_view_ohlcv'],
|
||||
[ /\.convertTradingViewToOHLCV\s/g, '.convert_trading_view_to_ohlcv'],
|
||||
[ /\.parseTransaction\s/g, '.parse_transaction'],
|
||||
[ /\.parseTransactions\s/g, '.parse_transactions'],
|
||||
[ /\.parseOrderBook\s/g, '.parse_order_book'],
|
||||
@@ -299,7 +307,9 @@ class Transpiler {
|
||||
[ /this\.stringToBase64\s/g, 'base64_encode' ],
|
||||
[ /this\.binaryToBase16\s/g, 'bin2hex' ],
|
||||
[ /this\.base64ToBinary\s/g, 'base64_decode' ],
|
||||
[ /this\.deepExtend\s/g, 'array_replace_recursive'],
|
||||
// deepExtend is commented for PHP because it does not overwrite linear arrays
|
||||
// a proper \ccxt\Exchange::deep_extend() base method is implemented instead
|
||||
// [ /this\.deepExtend\s/g, 'array_replace_recursive'],
|
||||
[ /(\w+)\.shift\s*\(\)/g, 'array_shift($1)' ],
|
||||
[ /(\w+)\.pop\s*\(\)/g, 'array_pop($1)' ],
|
||||
[ /Number\.MAX_SAFE_INTEGER/g, 'PHP_INT_MAX' ],
|
||||
@@ -382,12 +392,27 @@ class Transpiler {
|
||||
])
|
||||
}
|
||||
|
||||
getBaseClass () {
|
||||
return new Exchange ()
|
||||
}
|
||||
|
||||
getBaseMethods () {
|
||||
const baseExchange = this.getBaseClass ()
|
||||
let object = baseExchange
|
||||
let properties = []
|
||||
while (object !== Object.prototype) {
|
||||
properties = properties.concat (Object.getOwnPropertyNames (object))
|
||||
object = Object.getPrototypeOf (object)
|
||||
}
|
||||
return properties.filter (x => typeof baseExchange[x] === 'function')
|
||||
}
|
||||
|
||||
getPythonBaseMethods () {
|
||||
return []
|
||||
return this.getBaseMethods ()
|
||||
}
|
||||
|
||||
getPHPBaseMethods () {
|
||||
return []
|
||||
return this.getBaseMethods ()
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -589,10 +614,10 @@ class Transpiler {
|
||||
methods = methods.concat (this.getPHPBaseMethods ())
|
||||
|
||||
for (let method of methods) {
|
||||
const regex = new RegExp ('\\$this->(' + method + ')(\\s\\(|[^a-zA-Z0-9_])', 'g')
|
||||
const regex = new RegExp ('\\$this->(' + method + ')\\s?(\\(|[^a-zA-Z0-9_])', 'g')
|
||||
bodyAsString = bodyAsString.replace (regex,
|
||||
(match, p1, p2) => {
|
||||
return ((p2 === ' (') ?
|
||||
return ((p2 === '(') ?
|
||||
('$this->' + unCamelCase (p1) + p2) : // support direct php calls
|
||||
("array($this, '" + unCamelCase (p1) + "')" + p2)) // as well as passing instance methods as callables
|
||||
})
|
||||
@@ -748,7 +773,7 @@ class Transpiler {
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
transpileDerivedExchangeClass (contents) {
|
||||
transpileDerivedExchangeClass (contents, methodNames = undefined) {
|
||||
|
||||
let exchangeClassDeclarationMatches = contents.match (/^module\.exports\s*=\s*class\s+([\S]+)\s+extends\s+([\S]+)\s+{([\s\S]+?)^};*/m)
|
||||
|
||||
@@ -763,7 +788,7 @@ class Transpiler {
|
||||
let python3 = []
|
||||
let php = []
|
||||
|
||||
let methodNames = []
|
||||
methodNames = [] // methodNames || []
|
||||
|
||||
// run through all methods
|
||||
for (let i = 0; i < methods.length; i++) {
|
||||
@@ -839,7 +864,7 @@ class Transpiler {
|
||||
|
||||
// compile signature + body for PHP
|
||||
php.push ('');
|
||||
php.push (' public function ' + method + ' (' + phpArgs + ') {');
|
||||
php.push (' public function ' + method + '(' + phpArgs + ') {');
|
||||
php.push (phpBody);
|
||||
php.push (' }')
|
||||
|
||||
@@ -866,8 +891,25 @@ class Transpiler {
|
||||
try {
|
||||
|
||||
const { python2Folder, python3Folder, phpFolder } = options
|
||||
const contents = fs.readFileSync (jsFolder + filename, 'utf8')
|
||||
const { python2, python3, php, className, baseClass } = this.transpileDerivedExchangeClass (contents)
|
||||
const path = jsFolder + filename
|
||||
const contents = fs.readFileSync (path, 'utf8')
|
||||
|
||||
// function getMethodNames (object) {
|
||||
// let functions = []
|
||||
// let o = object
|
||||
// do {
|
||||
// functions = functions.concat (Object.getOwnPropertyNames (o))
|
||||
// } while (o = Object.getPrototypeOf (o))
|
||||
// return unique (functions.filter (f => (typeof object[f] === 'function')))
|
||||
// }
|
||||
// const exchangeClass = require ('.' + path)
|
||||
// const exchange = new exchangeClass ()
|
||||
// const methodNames = getMethodNames (exchange)
|
||||
// const { python2, python3, php, className, baseClass } =
|
||||
// this.transpileDerivedExchangeClass (contents, methodNames)
|
||||
|
||||
const { python2, python3, php, className, baseClass } =
|
||||
this.transpileDerivedExchangeClass (contents)
|
||||
|
||||
log.cyan ('Transpiling from', filename.yellow)
|
||||
|
||||
@@ -943,11 +985,12 @@ class Transpiler {
|
||||
|
||||
// ========================================================================
|
||||
|
||||
exportTypeScriptDeclarations (classes) {
|
||||
exportTypeScriptDeclarations (file, classes) {
|
||||
|
||||
const file = './ccxt.d.ts'
|
||||
const regex = /(?: export class [^\s]+ extends [^\s]+ \{\}[\r]?[\n])+/
|
||||
const replacement = Object.keys (classes).map (className => {
|
||||
log.bright.cyan ('Exporting TypeScript declarations →', file.yellow)
|
||||
|
||||
const regex = /\/[\n]{2}(?: export class [^\s]+ extends [^\s]+ \{\}[\r]?[\n])+/
|
||||
const replacement = "/\n\n" + Object.keys (classes).map (className => {
|
||||
const baseClass = classes[className]
|
||||
return ' export class ' + className + ' extends ' + baseClass + " {}"
|
||||
}).join ("\n") + "\n"
|
||||
@@ -968,34 +1011,91 @@ class Transpiler {
|
||||
[ /module\.exports = [^\;]+\;\n/s, '' ],
|
||||
]).trim ()
|
||||
|
||||
const message = 'Transpiling error hierachy →'
|
||||
const root = errorHierarchy['BaseError']
|
||||
|
||||
const { python3Body, phpBody } = this.transpileJavaScriptToPythonAndPHP ({ js })
|
||||
|
||||
const python3BodyIntellisense = python3Body + '\n\n' + Array.from (function* intellisense (map) {
|
||||
for (const key in map) {
|
||||
yield key + ' = Exception'
|
||||
yield* intellisense (map[key])
|
||||
// a helper to generate a list of exception class declarations
|
||||
// properly derived from corresponding parent classes according
|
||||
// to the error hierarchy
|
||||
|
||||
function intellisense (map, parent, generate, classes) {
|
||||
function* generator(map, parent, generate, classes) {
|
||||
for (const key in map) {
|
||||
yield generate (key, parent, classes)
|
||||
yield* generator (map[key], key, generate, classes)
|
||||
}
|
||||
}
|
||||
} (errorHierarchy['BaseError'])).join ('\n')
|
||||
|
||||
const message = 'Transpiling error hierachy →'
|
||||
|
||||
const python = {
|
||||
filename: './python/ccxt/base/errors.py',
|
||||
regex: /error_hierarchy = [\S\s]+= Exception/s,
|
||||
replacement: python3BodyIntellisense,
|
||||
return Array.from (generator (map, parent, generate, classes))
|
||||
}
|
||||
|
||||
log.bright.cyan (message, python.filename.yellow)
|
||||
replaceInFile (... Object.values (python))
|
||||
// Python -------------------------------------------------------------
|
||||
|
||||
const php = {
|
||||
filename:'./php/base/errors.php',
|
||||
regex: /\$error_hierarchy = .+?\n\)\;/s,
|
||||
replacement: phpBody,
|
||||
function pythonDeclareErrorClass (name, parent, classes) {
|
||||
classes.push (name)
|
||||
return [
|
||||
'class ' + name + '(' + parent + '):',
|
||||
' pass',
|
||||
'',
|
||||
'',
|
||||
].join ('\n');
|
||||
}
|
||||
|
||||
log.bright.cyan (message, php.filename.yellow)
|
||||
replaceInFile (... Object.values (php))
|
||||
const pythonBaseError = [
|
||||
'class BaseError(Exception):',
|
||||
' pass',
|
||||
'',
|
||||
'',
|
||||
].join ('\n');
|
||||
|
||||
const quote = (s) => "'" + s + "'" // helper to add quotes around class names
|
||||
|
||||
const pythonExports = [ 'error_hierarchy' ]
|
||||
const pythonErrors = intellisense (root, 'BaseError', pythonDeclareErrorClass, pythonExports)
|
||||
const pythonAll = '__all__ = [\n ' + pythonExports.map (quote).join (',\n ') + '\n]'
|
||||
|
||||
const python3BodyIntellisense = python3Body + '\n\n\n' + pythonBaseError + '\n' + pythonErrors.join ('\n') + '\n' + pythonAll + '\n'
|
||||
|
||||
const pythonFilename = './python/ccxt/base/errors.py'
|
||||
log.bright.cyan (message, pythonFilename.yellow)
|
||||
fs.writeFileSync (pythonFilename, python3BodyIntellisense)
|
||||
|
||||
// PHP ----------------------------------------------------------------
|
||||
|
||||
function phpDeclareErrorClass (name, parent) {
|
||||
return 'class ' + name + ' extends ' + parent + ' {};'
|
||||
}
|
||||
|
||||
const phpHeader = '<?php\n\nnamespace ccxt;\n\nuse Exception;\n\n'
|
||||
const phpBaseError = 'class BaseError extends Exception {};'
|
||||
const phpErrors = intellisense (root, 'BaseError', phpDeclareErrorClass)
|
||||
const phpBodyIntellisense = phpHeader + phpBody + '\n\n' + phpBaseError + '\n' + phpErrors.join ('\n')
|
||||
|
||||
const phpFilename = './php/base/errors.php'
|
||||
log.bright.cyan (message, phpFilename.yellow)
|
||||
fs.writeFileSync (phpFilename, phpBodyIntellisense)
|
||||
|
||||
// TypeScript ---------------------------------------------------------
|
||||
|
||||
function tsDeclareErrorClass (name, parent) {
|
||||
return 'export class ' + name + ' extends ' + parent + ' {}'
|
||||
}
|
||||
|
||||
const tsBaseError = [
|
||||
'export class BaseError extends Error {',
|
||||
' constructor(message: string);',
|
||||
'}',
|
||||
].join ('\n ')
|
||||
|
||||
const tsErrors = intellisense (root, 'BaseError', tsDeclareErrorClass)
|
||||
|
||||
const tsBodyIntellisense = tsBaseError + '\n\n ' + tsErrors.join ('\n ') + '\n\n'
|
||||
|
||||
const tsFilename = './ccxt.d.ts'
|
||||
log.bright.cyan (message, tsFilename.yellow)
|
||||
const regex = /export class BaseError[^}]+\}[\n][\n](?:\s+export class [a-zA-Z]+ extends [a-zA-Z]+ \{\}[\n])+[\n]/m
|
||||
replaceInFile (tsFilename, regex, tsBodyIntellisense)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1070,8 +1170,15 @@ class Transpiler {
|
||||
"from ccxt.base.decimal_to_precision import PAD_WITH_ZERO # noqa F401",
|
||||
"from ccxt.base.decimal_to_precision import NO_PADDING # noqa F401",
|
||||
"from ccxt.base.decimal_to_precision import number_to_string # noqa F401",
|
||||
"from ccxt.base.exchange import Exchange # noqa F401",
|
||||
"",
|
||||
"# ----------------------------------------------------------------------------",
|
||||
"",
|
||||
"def toWei(amount, decimals):",
|
||||
" return Exchange.to_wei(amount, decimals)",
|
||||
"",
|
||||
"",
|
||||
"def fromWei(amount, decimals):",
|
||||
" return Exchange.from_wei(amount, decimals)",
|
||||
"",
|
||||
"",
|
||||
].join ("\n")
|
||||
@@ -1095,6 +1202,12 @@ class Transpiler {
|
||||
"function number_to_string ($x) {",
|
||||
" return Exchange::number_to_string ($x);",
|
||||
"}",
|
||||
"function toWei ($amount, $decimals) {",
|
||||
" return Exchange::to_wei ($amount, $decimals);",
|
||||
"}",
|
||||
"function fromWei ($amount, $decimals) {",
|
||||
" return Exchange::from_wei ($amount, $decimals);",
|
||||
"}",
|
||||
"",
|
||||
].join ("\n")
|
||||
|
||||
@@ -1190,6 +1303,8 @@ class Transpiler {
|
||||
createFolderRecursively (python3Folder)
|
||||
createFolderRecursively (phpFolder)
|
||||
|
||||
//*
|
||||
|
||||
const classes = this.transpileDerivedExchangeFiles ('./js/', options, pattern)
|
||||
|
||||
if (classes === null) {
|
||||
@@ -1199,7 +1314,9 @@ class Transpiler {
|
||||
|
||||
// HINT: if we're going to support specific class definitions
|
||||
// this process won't work anymore as it will override the definitions
|
||||
this.exportTypeScriptDeclarations (classes)
|
||||
this.exportTypeScriptDeclarations ('./ccxt.d.ts', classes)
|
||||
|
||||
//*/
|
||||
|
||||
this.transpileErrorHierarchy ()
|
||||
|
||||
|
||||
Reference in new issue
Block a user