ccxt-look 1.81.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/.cache/eslintcache +1 -0
  2. package/.dockerignore +6 -0
  3. package/.eslintignore +1 -0
  4. package/.gitattributes +5 -0
  5. package/.readthedocs.yaml +16 -0
  6. package/CONTRIBUTING.md +1049 -0
  7. package/LICENSE.txt +21 -0
  8. package/README.md +537 -0
  9. package/SECURITY.md +5 -0
  10. package/build/cleanup-old-tags.js +94 -0
  11. package/build/countries.js +256 -0
  12. package/build/export-exchanges.js +520 -0
  13. package/build/fs.js +51 -0
  14. package/build/transpile.js +1772 -0
  15. package/build/vss.js +78 -0
  16. package/ccxt.browser.js +7 -0
  17. package/ccxt.d.ts +692 -0
  18. package/ccxt.js +171 -0
  19. package/cleanup.sh +2 -0
  20. package/composer-install.sh +20 -0
  21. package/dist/ccxt.browser.js +208383 -0
  22. package/gource.sh +3 -0
  23. package/index.html +7 -0
  24. package/js/.eslintrc +87 -0
  25. package/js/aax.js +2686 -0
  26. package/js/ascendex.js +2584 -0
  27. package/js/base/.eslintrc.js +43 -0
  28. package/js/base/Exchange.js +2371 -0
  29. package/js/base/Precise.js +283 -0
  30. package/js/base/errorHierarchy.js +47 -0
  31. package/js/base/errors.js +55 -0
  32. package/js/base/functions/crypto.js +158 -0
  33. package/js/base/functions/encode.js +118 -0
  34. package/js/base/functions/generic.js +270 -0
  35. package/js/base/functions/misc.js +138 -0
  36. package/js/base/functions/number.js +329 -0
  37. package/js/base/functions/platform.js +38 -0
  38. package/js/base/functions/string.js +21 -0
  39. package/js/base/functions/throttle.js +79 -0
  40. package/js/base/functions/time.js +210 -0
  41. package/js/base/functions/type.js +66 -0
  42. package/js/base/functions.js +28 -0
  43. package/js/bequant.js +32 -0
  44. package/js/bibox.js +1407 -0
  45. package/js/bigone.js +1366 -0
  46. package/js/binance.js +5652 -0
  47. package/js/binancecoinm.js +46 -0
  48. package/js/binanceus.js +46 -0
  49. package/js/binanceusdm.js +49 -0
  50. package/js/bit2c.js +535 -0
  51. package/js/bitbank.js +842 -0
  52. package/js/bitbay.js +16 -0
  53. package/js/bitbns.js +1073 -0
  54. package/js/bitcoincom.js +15 -0
  55. package/js/bitfinex.js +1433 -0
  56. package/js/bitfinex2.js +2025 -0
  57. package/js/bitflyer.js +840 -0
  58. package/js/bitforex.js +614 -0
  59. package/js/bitget.js +2397 -0
  60. package/js/bithumb.js +980 -0
  61. package/js/bitmart.js +2516 -0
  62. package/js/bitmex.js +1809 -0
  63. package/js/bitopro.js +1443 -0
  64. package/js/bitpanda.js +1782 -0
  65. package/js/bitrue.js +1747 -0
  66. package/js/bitso.js +1062 -0
  67. package/js/bitstamp.js +1757 -0
  68. package/js/bitstamp1.js +343 -0
  69. package/js/bittrex.js +1876 -0
  70. package/js/bitvavo.js +1579 -0
  71. package/js/bkex.js +1233 -0
  72. package/js/bl3p.js +346 -0
  73. package/js/blockchaincom.js +969 -0
  74. package/js/btcalpha.js +680 -0
  75. package/js/btcbox.js +477 -0
  76. package/js/btcmarkets.js +1022 -0
  77. package/js/btctradeua.js +466 -0
  78. package/js/btcturk.js +734 -0
  79. package/js/buda.js +946 -0
  80. package/js/bw.js +1265 -0
  81. package/js/bybit.js +3372 -0
  82. package/js/bytetrade.js +1336 -0
  83. package/js/cdax.js +1646 -0
  84. package/js/cex.js +1410 -0
  85. package/js/coinbase.js +1342 -0
  86. package/js/coinbaseprime.js +31 -0
  87. package/js/coinbasepro.js +1466 -0
  88. package/js/coincheck.js +755 -0
  89. package/js/coinex.js +3400 -0
  90. package/js/coinfalcon.js +880 -0
  91. package/js/coinmate.js +794 -0
  92. package/js/coinone.js +816 -0
  93. package/js/coinspot.js +345 -0
  94. package/js/crex24.js +1636 -0
  95. package/js/cryptocom.js +1832 -0
  96. package/js/currencycom.js +1748 -0
  97. package/js/delta.js +1547 -0
  98. package/js/deribit.js +2148 -0
  99. package/js/digifinex.js +1585 -0
  100. package/js/eqonex.js +1660 -0
  101. package/js/exmo.js +1670 -0
  102. package/js/fairdesk.js +1231 -0
  103. package/js/flowbtc.js +35 -0
  104. package/js/fmfwio.js +34 -0
  105. package/js/ftx.js +2751 -0
  106. package/js/ftxus.js +38 -0
  107. package/js/gateio.js +4174 -0
  108. package/js/gemini.js +1397 -0
  109. package/js/hitbtc.js +1343 -0
  110. package/js/hitbtc3.js +2329 -0
  111. package/js/hollaex.js +1486 -0
  112. package/js/huobi.js +5706 -0
  113. package/js/huobijp.js +1710 -0
  114. package/js/huobipro.js +18 -0
  115. package/js/idex.js +1439 -0
  116. package/js/independentreserve.js +649 -0
  117. package/js/indodax.js +742 -0
  118. package/js/itbit.js +722 -0
  119. package/js/kraken.js +2179 -0
  120. package/js/kucoin.js +2571 -0
  121. package/js/kucoinfutures.js +1771 -0
  122. package/js/kuna.js +809 -0
  123. package/js/latoken.js +1445 -0
  124. package/js/lbank.js +760 -0
  125. package/js/liquid.js +1432 -0
  126. package/js/luno.js +873 -0
  127. package/js/lykke.js +1147 -0
  128. package/js/mercado.js +771 -0
  129. package/js/mexc.js +3151 -0
  130. package/js/ndax.js +2233 -0
  131. package/js/novadax.js +1318 -0
  132. package/js/oceanex.js +816 -0
  133. package/js/okcoin.js +3841 -0
  134. package/js/okex.js +16 -0
  135. package/js/okex5.js +16 -0
  136. package/js/okx.js +4795 -0
  137. package/js/paymium.js +498 -0
  138. package/js/phemex.js +2957 -0
  139. package/js/poloniex.js +1674 -0
  140. package/js/probit.js +1346 -0
  141. package/js/qtrade.js +1588 -0
  142. package/js/ripio.js +1061 -0
  143. package/js/static_dependencies/BN/bn.js +3526 -0
  144. package/js/static_dependencies/README.md +1 -0
  145. package/js/static_dependencies/crypto-js/crypto-js.js +5988 -0
  146. package/js/static_dependencies/elliptic/lib/elliptic/curve/base.js +375 -0
  147. package/js/static_dependencies/elliptic/lib/elliptic/curve/edwards.js +433 -0
  148. package/js/static_dependencies/elliptic/lib/elliptic/curve/index.js +8 -0
  149. package/js/static_dependencies/elliptic/lib/elliptic/curve/mont.js +180 -0
  150. package/js/static_dependencies/elliptic/lib/elliptic/curve/short.js +938 -0
  151. package/js/static_dependencies/elliptic/lib/elliptic/curves.js +204 -0
  152. package/js/static_dependencies/elliptic/lib/elliptic/ec/index.js +240 -0
  153. package/js/static_dependencies/elliptic/lib/elliptic/ec/key.js +119 -0
  154. package/js/static_dependencies/elliptic/lib/elliptic/ec/signature.js +24 -0
  155. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/index.js +145 -0
  156. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/key.js +100 -0
  157. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/signature.js +65 -0
  158. package/js/static_dependencies/elliptic/lib/elliptic/precomputed/secp256k1.js +780 -0
  159. package/js/static_dependencies/elliptic/lib/elliptic/utils.js +214 -0
  160. package/js/static_dependencies/elliptic/lib/elliptic.js +22 -0
  161. package/js/static_dependencies/elliptic/lib/hmac-drbg/hmac-drbg.js +114 -0
  162. package/js/static_dependencies/fetch-ponyfill/fetch-node.js +39 -0
  163. package/js/static_dependencies/node-fetch/index.js +1564 -0
  164. package/js/static_dependencies/node-rsa/NodeRSA.js +223 -0
  165. package/js/static_dependencies/node-rsa/asn1/ber/errors.js +13 -0
  166. package/js/static_dependencies/node-rsa/asn1/ber/index.js +21 -0
  167. package/js/static_dependencies/node-rsa/asn1/ber/reader.js +262 -0
  168. package/js/static_dependencies/node-rsa/asn1/ber/types.js +36 -0
  169. package/js/static_dependencies/node-rsa/asn1/index.js +17 -0
  170. package/js/static_dependencies/node-rsa/encryptEngines/js.js +34 -0
  171. package/js/static_dependencies/node-rsa/formats/components.js +71 -0
  172. package/js/static_dependencies/node-rsa/formats/formats.js +31 -0
  173. package/js/static_dependencies/node-rsa/formats/pkcs1.js +148 -0
  174. package/js/static_dependencies/node-rsa/formats/pkcs8.js +187 -0
  175. package/js/static_dependencies/node-rsa/libs/jsbn.js +1252 -0
  176. package/js/static_dependencies/node-rsa/libs/rsa.js +147 -0
  177. package/js/static_dependencies/node-rsa/schemes/pkcs1.js +176 -0
  178. package/js/static_dependencies/node-rsa/schemes/schemes.js +21 -0
  179. package/js/static_dependencies/node-rsa/utils.js +98 -0
  180. package/js/static_dependencies/qs/formats.js +18 -0
  181. package/js/static_dependencies/qs/index.js +11 -0
  182. package/js/static_dependencies/qs/parse.js +242 -0
  183. package/js/static_dependencies/qs/stringify.js +269 -0
  184. package/js/static_dependencies/qs/utils.js +230 -0
  185. package/js/stex.js +1925 -0
  186. package/js/test/.eslintrc.js +42 -0
  187. package/js/test/Exchange/test.balance.js +61 -0
  188. package/js/test/Exchange/test.borrowRate.js +32 -0
  189. package/js/test/Exchange/test.currency.js +52 -0
  190. package/js/test/Exchange/test.fetchBalance.js +23 -0
  191. package/js/test/Exchange/test.fetchBorrowInterest.js +59 -0
  192. package/js/test/Exchange/test.fetchBorrowRate.js +32 -0
  193. package/js/test/Exchange/test.fetchBorrowRates.js +28 -0
  194. package/js/test/Exchange/test.fetchClosedOrders.js +32 -0
  195. package/js/test/Exchange/test.fetchCurrencies.js +35 -0
  196. package/js/test/Exchange/test.fetchDeposits.js +31 -0
  197. package/js/test/Exchange/test.fetchFundingFees.js +19 -0
  198. package/js/test/Exchange/test.fetchFundingRateHistory.js +40 -0
  199. package/js/test/Exchange/test.fetchL2OrderBook.js +23 -0
  200. package/js/test/Exchange/test.fetchLedger.js +42 -0
  201. package/js/test/Exchange/test.fetchLeverageTiers.js +33 -0
  202. package/js/test/Exchange/test.fetchMarketLeverageTiers.js +22 -0
  203. package/js/test/Exchange/test.fetchMarkets.js +33 -0
  204. package/js/test/Exchange/test.fetchMyTrades.js +42 -0
  205. package/js/test/Exchange/test.fetchOHLCV.js +46 -0
  206. package/js/test/Exchange/test.fetchOpenOrders.js +36 -0
  207. package/js/test/Exchange/test.fetchOrderBook.js +25 -0
  208. package/js/test/Exchange/test.fetchOrderBooks.js +35 -0
  209. package/js/test/Exchange/test.fetchOrders.js +41 -0
  210. package/js/test/Exchange/test.fetchPositions.js +47 -0
  211. package/js/test/Exchange/test.fetchStatus.js +35 -0
  212. package/js/test/Exchange/test.fetchTicker.js +38 -0
  213. package/js/test/Exchange/test.fetchTickers.js +49 -0
  214. package/js/test/Exchange/test.fetchTrades.js +39 -0
  215. package/js/test/Exchange/test.fetchTradingFee.js +18 -0
  216. package/js/test/Exchange/test.fetchTradingFees.js +22 -0
  217. package/js/test/Exchange/test.fetchTransactions.js +31 -0
  218. package/js/test/Exchange/test.fetchWithdrawals.js +31 -0
  219. package/js/test/Exchange/test.ledgerItem.js +46 -0
  220. package/js/test/Exchange/test.leverageTier.js +33 -0
  221. package/js/test/Exchange/test.loadMarkets.js +35 -0
  222. package/js/test/Exchange/test.market.js +129 -0
  223. package/js/test/Exchange/test.ohlcv.js +33 -0
  224. package/js/test/Exchange/test.order.js +62 -0
  225. package/js/test/Exchange/test.orderbook.js +61 -0
  226. package/js/test/Exchange/test.position.js +21 -0
  227. package/js/test/Exchange/test.throttle.js +94 -0
  228. package/js/test/Exchange/test.ticker.js +95 -0
  229. package/js/test/Exchange/test.trade.js +68 -0
  230. package/js/test/Exchange/test.tradingFee.js +34 -0
  231. package/js/test/Exchange/test.transaction.js +35 -0
  232. package/js/test/base/.eslintrc +38 -0
  233. package/js/test/base/functions/test.crypto.js +110 -0
  234. package/js/test/base/functions/test.datetime.js +62 -0
  235. package/js/test/base/functions/test.generic.js +152 -0
  236. package/js/test/base/functions/test.number.js +362 -0
  237. package/js/test/base/functions/test.time.js +56 -0
  238. package/js/test/base/functions/test.type.js +53 -0
  239. package/js/test/base/test.base.js +193 -0
  240. package/js/test/errors/test.InsufficientFunds.js +86 -0
  241. package/js/test/errors/test.InvalidNonce.js +64 -0
  242. package/js/test/errors/test.InvalidOrder.js +35 -0
  243. package/js/test/errors/test.OrderNotFound.js +39 -0
  244. package/js/test/test.js +426 -0
  245. package/js/test/test.timeout_hang.js +12 -0
  246. package/js/therock.js +1431 -0
  247. package/js/tidebit.js +632 -0
  248. package/js/tidex.js +939 -0
  249. package/js/timex.js +1283 -0
  250. package/js/upbit.js +1622 -0
  251. package/js/vcc.js +1353 -0
  252. package/js/wavesexchange.js +2185 -0
  253. package/js/wazirx.js +732 -0
  254. package/js/whitebit.js +1352 -0
  255. package/js/woo.js +1577 -0
  256. package/js/xena.js +1948 -0
  257. package/js/yobit.js +1129 -0
  258. package/js/zaif.js +647 -0
  259. package/js/zb.js +4088 -0
  260. package/js/zipmex.js +40 -0
  261. package/js/zonda.js +1497 -0
  262. package/multilang.sh +159 -0
  263. package/package.json +591 -0
  264. package/postinstall.js +103 -0
@@ -0,0 +1,520 @@
1
+ // ----------------------------------------------------------------------------
2
+ // Usage:
3
+ //
4
+ // npm run export-exchanges
5
+ // ----------------------------------------------------------------------------
6
+
7
+ "use strict";
8
+
9
+ const fs = require ('fs')
10
+ , countries = require ('./countries')
11
+ , asTable = require ('as-table').configure ({
12
+ delimiter: '|',
13
+ print: (x) => ' ' + x + ' '
14
+ })
15
+ , execSync = require ('child_process').execSync
16
+ , log = require ('ololog').unlimited
17
+ , ansi = require ('ansicolor').nice
18
+ , { keys, values, entries, fromEntries } = Object
19
+ , { replaceInFile } = require ('./fs.js')
20
+
21
+ // ----------------------------------------------------------------------------
22
+
23
+ function cloneGitHubWiki (gitWikiPath) {
24
+
25
+ if (!fs.existsSync (gitWikiPath)) {
26
+ log.bright.cyan ('Cloning ccxt.wiki...')
27
+ execSync ('git clone https://github.com/ccxt/ccxt.wiki.git ' + gitWikiPath)
28
+ }
29
+ }
30
+
31
+ // ----------------------------------------------------------------------------
32
+
33
+ function logExportExchanges (filename, regex, replacement) {
34
+ log.bright.cyan ('Exporting exchanges →', filename.yellow)
35
+ replaceInFile (filename, regex, replacement)
36
+ }
37
+
38
+ // ----------------------------------------------------------------------------
39
+
40
+ function getIncludedExchangeIds () {
41
+
42
+ const includedIds = fs.readFileSync ('exchanges.cfg')
43
+ .toString () // Buffer → String
44
+ .split ('\n') // String → Array
45
+ .map (line => line.split ('#')[0].trim ()) // trim comments
46
+ .filter (exchange => exchange); // filter empty lines
47
+
48
+ const isIncluded = (id) => ((includedIds.length === 0) || includedIds.includes (id))
49
+
50
+ const ids = fs.readdirSync ('./js/')
51
+ .filter (file => file.match (/[a-zA-Z0-9_-]+.js$/))
52
+ .map (file => file.slice (0, -3))
53
+ .filter (isIncluded);
54
+
55
+ return ids
56
+ }
57
+
58
+ // ----------------------------------------------------------------------------
59
+
60
+ function exportExchanges (replacements) {
61
+
62
+ log.bright.yellow ('Exporting exchanges...')
63
+
64
+ replacements.forEach (({ file, regex, replacement }) => {
65
+ logExportExchanges (file, regex, replacement)
66
+ })
67
+
68
+ log.bright.green ('Base sources updated successfully.')
69
+ }
70
+
71
+ // ----------------------------------------------------------------------------
72
+
73
+ function createExchanges (ids) {
74
+
75
+ const ccxt = require ('../ccxt.js')
76
+
77
+ const createExchange = (id) => {
78
+ ccxt[id].prototype.checkRequiredDependencies = () => {} // suppress it
79
+ return new (ccxt)[id] ()
80
+ }
81
+
82
+ return ccxt.indexBy (ids.map (createExchange), 'id')
83
+ }
84
+
85
+ // ----------------------------------------------------------------------------
86
+
87
+ const ccxtCertifiedBadge = '[![CCXT Certified](https://img.shields.io/badge/CCXT-Certified-green.svg)](https://github.com/ccxt/ccxt/wiki/Certification)'
88
+ , ccxtProBadge = '[![CCXT Pro](https://img.shields.io/badge/CCXT-Pro-black)](https://ccxt.pro)'
89
+
90
+ // ----------------------------------------------------------------------------
91
+
92
+ function getFirstWebsiteUrl (exchange) {
93
+ return Array.isArray (exchange.urls.www) ? exchange.urls.www[0] : exchange.urls.www
94
+ }
95
+
96
+ // ----------------------------------------------------------------------------
97
+
98
+ function getReferralUrlOrWebsiteUrl (exchange) {
99
+ return exchange.urls.referral ?
100
+ (exchange.urls.referral.url ? exchange.urls.referral.url : exchange.urls.referral) :
101
+ getFirstWebsiteUrl (exchange)
102
+ }
103
+
104
+ // ----------------------------------------------------------------------------
105
+
106
+ function getReferralDiscountBadgeLink (exchange) {
107
+ const url = getReferralUrlOrWebsiteUrl (exchange)
108
+ if (exchange.urls.referral && exchange.urls.referral.discount) {
109
+ const discountPercentage = parseInt (exchange.urls.referral.discount * 100)
110
+
111
+ // this badge does not work with a minus sign
112
+ // const badge = '(https://img.shields.io/badge/fee-%2D' + discountPercentage.toString () + '%25-yellow)'
113
+
114
+ const badge = '(https://img.shields.io/static/v1?label=Fee&message=%2d' + discountPercentage.toString () + '%25&color=orange)'
115
+ const alt = "![Sign up with " + exchange.name + " using CCXT's referral link for a " + discountPercentage.toString () + "% discount!]"
116
+ return '[' + alt + badge + '](' + url + ')'
117
+ } else {
118
+ return ''
119
+ }
120
+ }
121
+
122
+ // ----------------------------------------------------------------------------
123
+
124
+ function getFirstDocUrl (exchange) {
125
+ return Array.isArray (exchange.urls.doc) ? exchange.urls.doc[0] : exchange.urls.doc
126
+ }
127
+
128
+ // ----------------------------------------------------------------------------
129
+
130
+
131
+ function getVersion (exchange) {
132
+ return exchange.version ? exchange.version.replace (/[^0-9\.]+/, '') : '\*'
133
+ }
134
+
135
+ // ----------------------------------------------------------------------------
136
+
137
+ function getVersionLink (exchange) {
138
+ const version = getVersion (exchange)
139
+ , doc = getFirstDocUrl (exchange)
140
+ return '[' + version + '](' + doc + ')'
141
+ }
142
+
143
+ // ----------------------------------------------------------------------------
144
+
145
+ function getVersionBadge (exchange) {
146
+ const version = getVersion (exchange)
147
+ , doc = getFirstDocUrl (exchange)
148
+ return '[![API Version ' + version + '](https://img.shields.io/badge/' + version + '-lightgray)](' + doc + ')'
149
+ }
150
+
151
+ // ----------------------------------------------------------------------------
152
+
153
+ function createMarkdownExchange (exchange) {
154
+ const url = getReferralUrlOrWebsiteUrl (exchange)
155
+ return {
156
+ 'logo': '[![' + exchange.id + '](' + exchange.urls.logo + ')](' + url + ')',
157
+ 'id': exchange.id,
158
+ 'name': '[' + exchange.name + '](' + url + ')',
159
+ 'ver': getVersionBadge (exchange),
160
+ 'certified': exchange.certified ? ccxtCertifiedBadge : '',
161
+ 'pro': exchange.pro ? ccxtProBadge : '',
162
+ }
163
+ }
164
+
165
+ // ----------------------------------------------------------------------------
166
+
167
+ function createMarkdownListOfExchanges (exchanges) {
168
+ return exchanges.map ((exchange) => createMarkdownExchange (exchange))
169
+ }
170
+
171
+ // ----------------------------------------------------------------------------
172
+
173
+ function createMarkdownListOfCertifiedExchanges (exchanges) {
174
+ return exchanges.map ((exchange) => {
175
+ const discount = getReferralDiscountBadgeLink (exchange)
176
+ return { ... createMarkdownExchange (exchange), discount }
177
+ })
178
+ }
179
+
180
+ // ----------------------------------------------------------------------------
181
+
182
+ const sortByCountry = (a, b) => {
183
+ if (a['country / region'] > b['country / region']) {
184
+ return 1
185
+ } else if (a['country / region'] < b['country / region']) {
186
+ return -1;
187
+ } else {
188
+ if (a['id'] > b['id']) {
189
+ return 1;
190
+ } else if (a['id'] < b['id']) {
191
+ return -1;
192
+ } else {
193
+ return 0;
194
+ }
195
+ }
196
+ }
197
+
198
+ // ----------------------------------------------------------------------------
199
+
200
+ function createMarkdownListOfExchangesByCountries (exchanges) {
201
+
202
+ const exchangesByCountries = []
203
+
204
+ keys (countries).forEach (code => {
205
+
206
+ exchanges.forEach (exchange => {
207
+
208
+ const exchangeInCountry =
209
+ (Array.isArray (exchange.countries) && exchange.countries.includes (code)) ||
210
+ (code === exchange.countries)
211
+
212
+ if (exchangeInCountry) {
213
+
214
+ const { logo, id, name, ver } = createMarkdownExchange (exchange)
215
+
216
+ exchangesByCountries.push ({
217
+ 'country / region': countries[code],
218
+ logo,
219
+ id,
220
+ name,
221
+ ver,
222
+ })
223
+ }
224
+ })
225
+ });
226
+
227
+ return exchangesByCountries.sort (sortByCountry)
228
+ }
229
+
230
+ // ----------------------------------------------------------------------------
231
+
232
+ function createMarkdownTable (array, markdownMethod, centeredColumns) {
233
+
234
+ array = markdownMethod (array)
235
+
236
+ const table = asTable (array)
237
+ const lines = table.split ("\n")
238
+
239
+ //
240
+ // asTable creates a header underline like
241
+ //
242
+ // logo | id | name | version | certified | pro
243
+ // ----------------------------------------------
244
+ //
245
+ // we fix it to match markdown underline like
246
+ //
247
+ // logo | id | name | version | certified | pro
248
+ // ------|----|------|---------|-----------|-----
249
+ //
250
+
251
+ const underline = lines[0].replace (/[^\|]/g, '-')
252
+
253
+ //
254
+ // ver and doc columns should be centered so we convert it to
255
+ //
256
+ // logo | id | name | version | certified | pro
257
+ // ------|----|------|:-------:|-----------|-----
258
+ //
259
+
260
+ const columns = underline.split ('|')
261
+ for (const i of centeredColumns) {
262
+ columns[i] = ':' + columns[i].slice (1, columns[i].length - 1) + ':'
263
+ }
264
+
265
+ lines.splice (1, 1, columns.join ('|'))
266
+
267
+ //
268
+ // prepend and append a vertical bar to each line
269
+ //
270
+ // | logo | id | name | version | certified | pro |
271
+ // |------|----|------|:-------:|-----------|-----|
272
+ //
273
+
274
+ return lines.map (line => '|' + line + '|').join ("\n")
275
+ }
276
+
277
+ // ----------------------------------------------------------------------------
278
+
279
+ function exportSupportedAndCertifiedExchanges (exchanges, { allExchangesPaths, certifiedExchangesPaths, exchangesByCountriesPaths, proExchangesPaths }) {
280
+
281
+ // const aliases = [ 'hitbtc2', 'huobipro' ] // aliases are not shown tables for deduplication
282
+
283
+ const arrayOfExchanges = values (exchanges).filter (exchange => !exchange.alias)
284
+ const numExchanges = arrayOfExchanges.length
285
+
286
+ if (allExchangesPaths && numExchanges) {
287
+ const supportedExchangesMarkdownTable = createMarkdownTable (arrayOfExchanges, createMarkdownListOfExchanges, [ 3 ])
288
+ , beginning = "The CCXT library currently supports the following "
289
+ , ending = " cryptocurrency exchange markets and trading APIs:\n\n"
290
+ , totalString = beginning + numExchanges + ending
291
+ , allExchangesReplacement = totalString + supportedExchangesMarkdownTable + "$1"
292
+ , allExchangesRegex = new RegExp ("[^\n]+[\n]{2}\\| logo[^`]+\\|([\n][\n]|[\n]$|$)", 'm')
293
+ for (const path of allExchangesPaths) {
294
+ logExportExchanges (path, allExchangesRegex, allExchangesReplacement)
295
+ }
296
+ }
297
+
298
+ const proExchanges = arrayOfExchanges.filter (exchange => exchange.pro)
299
+ const numProExchanges = proExchanges.length
300
+ if (proExchangesPaths && numProExchanges) {
301
+ const proExchangesMarkdownTable = createMarkdownTable (proExchanges, createMarkdownListOfExchanges, [ 3 ])
302
+ , beginning = "The CCXT Pro library currently supports the following "
303
+ , ending = " cryptocurrency exchange markets and WebSocket trading APIs:\n\n"
304
+ , totalString = beginning + numProExchanges + ending
305
+ , proExchangesReplacement = totalString + proExchangesMarkdownTable + "$1"
306
+ , proExchangesRegex = new RegExp ("[^\n]+[\n]{2}\\|[^`]+\\|([\n][\n]|[\n]$|$)", 'm')
307
+ for (const path of proExchangesPaths) {
308
+ logExportExchanges (path, proExchangesRegex, proExchangesReplacement)
309
+ }
310
+ }
311
+
312
+ const certifiedExchanges = arrayOfExchanges.filter (exchange => exchange.certified)
313
+ if (certifiedExchangesPaths && certifiedExchanges.length) {
314
+ const certifiedExchangesMarkdownTable = createMarkdownTable (certifiedExchanges, createMarkdownListOfCertifiedExchanges, [ 3, 6 ])
315
+ , certifiedExchangesReplacement = '$1' + certifiedExchangesMarkdownTable + "\n"
316
+ , certifiedExchangesRegex = new RegExp ("^(## Certified Cryptocurrency Exchanges\n{3})(?:\\|.+\\|$\n)+", 'm')
317
+ for (const path of certifiedExchangesPaths) {
318
+ logExportExchanges (path, certifiedExchangesRegex, certifiedExchangesReplacement)
319
+ }
320
+ }
321
+
322
+ if (exchangesByCountriesPaths) {
323
+ const exchangesByCountriesMarkdownTable = createMarkdownTable (arrayOfExchanges, createMarkdownListOfExchangesByCountries, [ 4 ])
324
+ const result = "# Exchanges By Country\n\nThe ccxt library currently supports the following cryptocurrency exchange markets and trading APIs:\n\n" + exchangesByCountriesMarkdownTable + "\n\n"
325
+ for (const path of exchangesByCountriesPaths) {
326
+ fs.truncateSync (path)
327
+ fs.writeFileSync (path, result)
328
+ }
329
+ }
330
+ }
331
+
332
+ // ----------------------------------------------------------------------------
333
+
334
+ function exportExchangeIdsToExchangesJson (exchanges) {
335
+ log.bright ('Exporting exchange ids to'.cyan, 'exchanges.json'.yellow)
336
+ const ids = keys (exchanges)
337
+ console.log (ids)
338
+ fs.writeFileSync ('exchanges.json', JSON.stringify ({ ids }, null, 4))
339
+ }
340
+
341
+ // ----------------------------------------------------------------------------
342
+
343
+ function exportWikiToGitHub (wikiPath, gitWikiPath) {
344
+
345
+ log.bright.cyan ('Exporting wiki to GitHub')
346
+
347
+ const ccxtWikiFiles = {
348
+ 'README.md': 'Home.md',
349
+ 'Install.md': 'Install.md',
350
+ 'Manual.md': 'Manual.md',
351
+ 'Exchange-Markets.md': 'Exchange-Markets.md',
352
+ 'Exchange-Markets-By-Country.md': 'Exchange-Markets-By-Country.md',
353
+ 'ccxt.pro.md': 'ccxt.pro.md',
354
+ 'ccxt.pro.install.md': 'ccxt.pro.install.md',
355
+ 'ccxt.pro.manual.md': 'ccxt.pro.manual.md',
356
+ }
357
+
358
+ for (const [ sourceFile, destinationFile ] of entries (ccxtWikiFiles)) {
359
+
360
+ const sourcePath = wikiPath + '/' + sourceFile
361
+ const destinationPath = gitWikiPath + '/' + destinationFile
362
+ log.bright.cyan ('Exporting', sourcePath.yellow, '→', destinationPath.yellow)
363
+ fs.writeFileSync (destinationPath, fs.readFileSync (sourcePath))
364
+ }
365
+ }
366
+
367
+ // ----------------------------------------------------------------------------
368
+
369
+ function exportKeywordsToPackageJson (exchanges) {
370
+
371
+ log.bright ('Exporting exchange keywords to'.cyan, 'package.json'.yellow)
372
+
373
+ // const packageJSON = require ('../package.json')
374
+ const packageJSON = JSON.parse (fs.readFileSync ('./package.json'))
375
+ const keywords = new Set (packageJSON.keywords)
376
+
377
+ for (const ex of values (exchanges)) {
378
+ for (const url of Array.isArray (ex.urls.www) ? ex.urls.www : [ex.urls.www]) {
379
+ keywords.add (url.replace (/(http|https):\/\/(www\.)?/, '').replace (/\/.*/, ''))
380
+ }
381
+ keywords.add (ex.name)
382
+ }
383
+
384
+ packageJSON.keywords = values (fromEntries ([ ... keywords ].map (s => [ s.toLowerCase (), s ])));
385
+ fs.writeFileSync ('./package.json', JSON.stringify (packageJSON, null, 2) + "\n")
386
+ }
387
+
388
+ // ----------------------------------------------------------------------------
389
+
390
+ function flatten (nested, result = []) {
391
+ for (const key in nested) {
392
+ result.push (key)
393
+ if (Object.keys (nested[key]).length)
394
+ flatten (nested[key], result)
395
+ }
396
+ return result
397
+ }
398
+
399
+ // ----------------------------------------------------------------------------
400
+
401
+ function exportEverything () {
402
+ const ids = getIncludedExchangeIds ()
403
+ const errorHierarchy = require ('../js/base/errorHierarchy.js')
404
+ const flat = flatten (errorHierarchy)
405
+ flat.push ('error_hierarchy')
406
+
407
+ const replacements = [
408
+ {
409
+ file: './ccxt.js',
410
+ regex: /(?:const|var)\s+exchanges\s+\=\s+\{[^\}]+\}/,
411
+ replacement: "const exchanges = {\n" + ids.map (id => (" '" + id + "':").padEnd (30) + " require ('./js/" + id + ".js'),").join ("\n") + " \n}",
412
+ },
413
+ {
414
+ file: './python/ccxt/__init__.py',
415
+ regex: /exchanges \= \[[^\]]+\]/,
416
+ replacement: "exchanges = [\n" + " '" + ids.join ("',\n '") + "'," + "\n]",
417
+ },
418
+ {
419
+ file: './python/ccxt/__init__.py',
420
+ regex: /(?:from ccxt\.[^\.]+ import [^\s]+\s+\# noqa\: F401[\r]?[\n])+[\r]?[\n]exchanges/,
421
+ replacement: ids.map (id => ('from ccxt.' + id + ' import ' + id).padEnd (60) + '# noqa: F401').join ("\n") + "\n\nexchanges",
422
+ },
423
+ {
424
+ file: './python/ccxt/__init__.py',
425
+ regex: /(?:from ccxt\.base\.errors import [^\s]+\s+\# noqa\: F401[\r]?[\n])+[\r]?[\n]/,
426
+ replacement: flat.map (error => ('from ccxt.base.errors' + ' import ' + error).padEnd (60) + '# noqa: F401').join ("\n") + "\n\n",
427
+ },
428
+ {
429
+ file: './python/ccxt/async_support/__init__.py',
430
+ regex: /(?:from ccxt\.base\.errors import [^\s]+\s+\# noqa\: F401[\r]?[\n])+[\r]?[\n]/,
431
+ replacement: flat.map (error => ('from ccxt.base.errors' + ' import ' + error).padEnd (60) + '# noqa: F401').join ("\n") + "\n\n",
432
+ },
433
+ {
434
+ file: './python/ccxt/async_support/__init__.py',
435
+ regex: /(?:from ccxt\.async_support\.[^\.]+ import [^\s]+\s+\# noqa\: F401[\r]?[\n])+[\r]?[\n]exchanges/,
436
+ replacement: ids.map (id => ('from ccxt.async_support.' + id + ' import ' + id).padEnd (74) + '# noqa: F401').join ("\n") + "\n\nexchanges",
437
+ },
438
+ {
439
+ file: './python/ccxt/async_support/__init__.py',
440
+ regex: /exchanges \= \[[^\]]+\]/,
441
+ replacement: "exchanges = [\n" + " '" + ids.join ("',\n '") + "'," + "\n]",
442
+ },
443
+ {
444
+ file: './php/Exchange.php',
445
+ regex: /public static \$exchanges \= array\s*\([^\)]+\)/,
446
+ replacement: "public static $exchanges = array(\n '" + ids.join ("',\n '") + "',\n )",
447
+ },
448
+ ]
449
+
450
+ exportExchanges (replacements)
451
+
452
+ // strategically placed exactly here (we can require it AFTER the export)
453
+ const exchanges = createExchanges (ids)
454
+
455
+ const wikiPath = 'wiki'
456
+ , gitWikiPath = 'build/ccxt.wiki'
457
+
458
+ cloneGitHubWiki (gitWikiPath)
459
+
460
+ exportSupportedAndCertifiedExchanges (exchanges, {
461
+ allExchangesPaths: [
462
+ 'README.md',
463
+ wikiPath + '/Manual.md',
464
+ wikiPath + '/Exchange-Markets.md'
465
+ ],
466
+ certifiedExchangesPaths: [
467
+ 'README.md',
468
+ ],
469
+ exchangesByCountriesPaths: [
470
+ wikiPath + '/Exchange-Markets-By-Country.md'
471
+ ],
472
+ proExchangesPaths: [
473
+ wikiPath + '/ccxt.pro.manual.md',
474
+ ],
475
+ })
476
+
477
+ exportExchangeIdsToExchangesJson (exchanges)
478
+ exportWikiToGitHub (wikiPath, gitWikiPath)
479
+ exportKeywordsToPackageJson (exchanges)
480
+
481
+ log.bright.green ('Exported successfully.')
482
+ }
483
+
484
+ // ============================================================================
485
+ // main entry point
486
+
487
+ if (require.main === module) {
488
+
489
+ // if called directly like `node module`
490
+
491
+ exportEverything ()
492
+
493
+ } else {
494
+
495
+ // do nothing if required as a module
496
+ }
497
+
498
+ // ============================================================================
499
+
500
+ module.exports = {
501
+ cloneGitHubWiki,
502
+ createExchanges,
503
+ createMarkdownExchange,
504
+ createMarkdownListOfExchanges,
505
+ createMarkdownListOfCertifiedExchanges,
506
+ createMarkdownListOfExchangesByCountries,
507
+ getFirstWebsiteUrl,
508
+ getReferralUrlOrWebsiteUrl,
509
+ getFirstDocUrl,
510
+ getVersion,
511
+ getVersionLink,
512
+ getVersionBadge,
513
+ getIncludedExchangeIds,
514
+ exportExchanges,
515
+ exportSupportedAndCertifiedExchanges,
516
+ exportExchangeIdsToExchangesJson,
517
+ exportWikiToGitHub,
518
+ exportKeywordsToPackageJson,
519
+ exportEverything,
520
+ }
package/build/fs.js ADDED
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+
3
+ const fs = require ('fs')
4
+ , path = require ('path')
5
+
6
+ function replaceInFile (filename, regex, replacement) {
7
+ const contents = fs.readFileSync (filename, 'utf8')
8
+ const newContents = contents.replace (regex, replacement)
9
+ fs.truncateSync (filename)
10
+ fs.writeFileSync (filename, newContents)
11
+ }
12
+
13
+ function copyFile (oldName, newName) {
14
+ const contents = fs.readFileSync (oldName, 'utf8')
15
+ if (fs.existsSync (newName)) {
16
+ fs.truncateSync (newName)
17
+ }
18
+ fs.writeFileSync (newName, contents)
19
+ }
20
+
21
+ function overwriteFile (filename, contents) {
22
+ // log.cyan ('Overwriting → ' + filename.yellow)
23
+ fs.closeSync (fs.openSync (filename, 'a'));
24
+ fs.truncateSync (filename)
25
+ fs.writeFileSync (filename, contents)
26
+ }
27
+
28
+ function createFolder (folder) {
29
+ try {
30
+ fs.mkdirSync (folder)
31
+ } catch (err) {
32
+ if (err.code !== 'EEXIST') {
33
+ throw err
34
+ }
35
+ }
36
+ }
37
+
38
+ function createFolderRecursively (folder) {
39
+ const parts = folder.split (path.sep)
40
+ for (let i = 1; i <= parts.length; i++) {
41
+ createFolder (path.join.apply (null, parts.slice (0, i)))
42
+ }
43
+ }
44
+
45
+ module.exports = {
46
+ replaceInFile,
47
+ copyFile,
48
+ overwriteFile,
49
+ createFolder,
50
+ createFolderRecursively,
51
+ }