puvox-library 1.0.13 → 1.0.14
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.
- package/library_standard.js +229 -147
- package/package.json +1 -1
- package/test.js +4 -1
package/library_standard.js
CHANGED
@@ -158,151 +158,7 @@ const puvox_library =
|
|
158
158
|
stringToArrayToNumeric(arr){
|
159
159
|
return this.stringArrayToNumeric(this.stringToArray(arr));
|
160
160
|
},
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
// region: ####### from CCXT ##########
|
165
|
-
keys: Object.keys,
|
166
|
-
values: (x) => ((!isArray (x)) ? Object.values (x) : x),
|
167
|
-
extend: (...args) => Object.assign ({}, ...args), // NB: side-effect free
|
168
|
-
clone:(x) => (isArray (x) ? Array.from (x) : extend (x)),
|
169
|
-
index: (x) => new Set (values (x)),
|
170
|
-
ordered: (x) => x, // a stub to keep assoc keys in order (in JS it does nothing, it's mostly for Python)
|
171
|
-
unique: (x) => Array.from (index (x)),
|
172
|
-
arrayConcat: (a, b) => a.concat (b),
|
173
|
-
inArray (needle, haystack) {
|
174
|
-
return haystack.includes (needle);
|
175
|
-
},
|
176
|
-
toArray (object) {
|
177
|
-
return Object.values (object);
|
178
|
-
},
|
179
|
-
isEmpty (object) {
|
180
|
-
if (!object) {
|
181
|
-
return true;
|
182
|
-
}
|
183
|
-
return (Array.isArray (object) ? object : Object.keys (object)).length < 1;
|
184
|
-
},
|
185
|
-
keysort (x, out = {}) {
|
186
|
-
for (const k of keys (x).sort ()) {
|
187
|
-
out[k] = x[k];
|
188
|
-
}
|
189
|
-
return out;
|
190
|
-
},
|
191
|
-
indexBy (x, k, out = {}) {
|
192
|
-
// description: https://github.com/ccxt/ccxt/blob/master/js/base/functions/generic.js
|
193
|
-
for (const v of values (x)) {
|
194
|
-
if (k in v) {
|
195
|
-
out[v[k]] = v;
|
196
|
-
}
|
197
|
-
}
|
198
|
-
|
199
|
-
return out;
|
200
|
-
},
|
201
|
-
groupBy (x, k, out = {}) {
|
202
|
-
// description: https://github.com/ccxt/ccxt/blob/master/js/base/functions/generic.js
|
203
|
-
for (const v of values (x)) {
|
204
|
-
if (k in v) {
|
205
|
-
const p = v[k];
|
206
|
-
out[p] = out[p] || [];
|
207
|
-
out[p].push (v);
|
208
|
-
}
|
209
|
-
}
|
210
|
-
return out;
|
211
|
-
},
|
212
|
-
filterBy (x, k, value = undefined, out = []) {
|
213
|
-
// description: https://github.com/ccxt/ccxt/blob/master/js/base/functions/generic.js
|
214
|
-
for (const v of values (x)) {
|
215
|
-
if (v[k] === value) {
|
216
|
-
out.push (v);
|
217
|
-
}
|
218
|
-
}
|
219
|
-
return out;
|
220
|
-
},
|
221
|
-
sortBy: (array, key, descending = false, direction = descending ? -1 : 1) => array.sort ((a, b) => {
|
222
|
-
if (a[key] < b[key]) {
|
223
|
-
return -direction;
|
224
|
-
} else if (a[key] > b[key]) {
|
225
|
-
return direction;
|
226
|
-
} else {
|
227
|
-
return 0;
|
228
|
-
}
|
229
|
-
}),
|
230
|
-
sortBy2: (array, key1, key2, descending = false, direction = descending ? -1 : 1) => array.sort ((a, b) => {
|
231
|
-
if (a[key1] < b[key1]) {
|
232
|
-
return -direction;
|
233
|
-
} else if (a[key1] > b[key1]) {
|
234
|
-
return direction;
|
235
|
-
} else {
|
236
|
-
if (a[key2] < b[key2]) {
|
237
|
-
return -direction;
|
238
|
-
} else if (a[key2] > b[key2]) {
|
239
|
-
return direction;
|
240
|
-
} else {
|
241
|
-
return 0;
|
242
|
-
}
|
243
|
-
}
|
244
|
-
}),
|
245
|
-
flatten: function flatten (x, out = []) {
|
246
|
-
|
247
|
-
for (const v of x) {
|
248
|
-
if (isArray (v)) {
|
249
|
-
flatten (v, out);
|
250
|
-
} else {
|
251
|
-
out.push (v);
|
252
|
-
}
|
253
|
-
}
|
254
|
-
|
255
|
-
return out;
|
256
|
-
},
|
257
|
-
pluck: (x, k) => values (x).filter ((v) => k in v).map ((v) => v[k]),
|
258
|
-
omit (x, ...args) {
|
259
|
-
if (!Array.isArray (x)) {
|
260
|
-
|
261
|
-
const out = clone (x);
|
262
|
-
|
263
|
-
for (const k of args) {
|
264
|
-
if (isArray (k)) { // omit (x, ['a', 'b'])
|
265
|
-
for (const kk of k) {
|
266
|
-
delete out[kk];
|
267
|
-
}
|
268
|
-
} else {
|
269
|
-
delete out[k]; // omit (x, 'a', 'b')
|
270
|
-
}
|
271
|
-
}
|
272
|
-
|
273
|
-
return out;
|
274
|
-
}
|
275
|
-
|
276
|
-
return x;
|
277
|
-
},
|
278
|
-
sum (...xs) {
|
279
|
-
const ns = xs.filter (isNumber); // leave only numbers
|
280
|
-
return (ns.length > 0) ? ns.reduce ((a, b) => a + b, 0) : undefined;
|
281
|
-
},
|
282
|
-
deepExtend: function deepExtend (...xs) {
|
283
|
-
let out = undefined;
|
284
|
-
for (const x of xs) {
|
285
|
-
if (isDictionary (x)) {
|
286
|
-
if (!isDictionary (out)) {
|
287
|
-
out = {};
|
288
|
-
}
|
289
|
-
for (const k in x) { // eslint-disable-line guard-for-in
|
290
|
-
out[k] = deepExtend (out[k], x[k]);
|
291
|
-
}
|
292
|
-
} else {
|
293
|
-
out = x;
|
294
|
-
}
|
295
|
-
}
|
296
|
-
return out;
|
297
|
-
},
|
298
|
-
// endregion: ####### from CCXT ##########
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
161
|
+
|
306
162
|
objectCopy(obj){
|
307
163
|
return JSON.parse(JSON.stringify(obj));
|
308
164
|
},
|
@@ -1447,8 +1303,6 @@ const puvox_library =
|
|
1447
1303
|
)
|
1448
1304
|
},
|
1449
1305
|
|
1450
|
-
milliseconds(){ return (new Date().getTime()); },
|
1451
|
-
|
1452
1306
|
fancyTimeFormat(time)
|
1453
1307
|
{
|
1454
1308
|
var time = time.toFixed(0);
|
@@ -3089,6 +2943,234 @@ const puvox_library =
|
|
3089
2943
|
return filesList;
|
3090
2944
|
},
|
3091
2945
|
},
|
2946
|
+
|
2947
|
+
|
2948
|
+
|
2949
|
+
|
2950
|
+
|
2951
|
+
|
2952
|
+
|
2953
|
+
|
2954
|
+
|
2955
|
+
|
2956
|
+
|
2957
|
+
|
2958
|
+
|
2959
|
+
|
2960
|
+
|
2961
|
+
|
2962
|
+
|
2963
|
+
|
2964
|
+
|
2965
|
+
|
2966
|
+
// region: ####### from CCXT ##########
|
2967
|
+
// generic
|
2968
|
+
keys: Object.keys,
|
2969
|
+
values(x) { return ((!this.isArray (x)) ? Object.values (x) : x);},
|
2970
|
+
extend(...args) { return Object.assign ({}, ...args) ;}, // NB: side-effect free
|
2971
|
+
clone(x){ return (this.isArray (x) ? Array.from (x) : this.extend (x)) ;},
|
2972
|
+
index(x) { return new Set (this.values (x));},
|
2973
|
+
ordered: (x) => x, // a stub to keep assoc keys in order (in JS it does nothing, it's mostly for Python)
|
2974
|
+
unique(x) { return Array.from (this.index (x));},
|
2975
|
+
arrayConcat: (a, b) => a.concat (b),
|
2976
|
+
inArray (needle, haystack) {
|
2977
|
+
return haystack.includes (needle);
|
2978
|
+
},
|
2979
|
+
toArray (object) {
|
2980
|
+
return Object.values (object);
|
2981
|
+
},
|
2982
|
+
isEmpty (object) {
|
2983
|
+
if (!object) {
|
2984
|
+
return true;
|
2985
|
+
}
|
2986
|
+
return (Array.isArray (object) ? object : Object.keys (object)).length < 1;
|
2987
|
+
},
|
2988
|
+
keysort (x, out = {}) {
|
2989
|
+
for (const k of this.keys (x).sort ()) {
|
2990
|
+
out[k] = x[k];
|
2991
|
+
}
|
2992
|
+
return out;
|
2993
|
+
},
|
2994
|
+
indexBy (x, k, out = {}) {
|
2995
|
+
// description: https://github.com/ccxt/ccxt/blob/master/js/base/functions/generic.js
|
2996
|
+
for (const v of this.values (x)) {
|
2997
|
+
if (k in v) {
|
2998
|
+
out[v[k]] = v;
|
2999
|
+
}
|
3000
|
+
}
|
3001
|
+
|
3002
|
+
return out;
|
3003
|
+
},
|
3004
|
+
groupBy (x, k, out = {}) {
|
3005
|
+
// description: https://github.com/ccxt/ccxt/blob/master/js/base/functions/generic.js
|
3006
|
+
for (const v of this.values (x)) {
|
3007
|
+
if (k in v) {
|
3008
|
+
const p = v[k];
|
3009
|
+
out[p] = out[p] || [];
|
3010
|
+
out[p].push (v);
|
3011
|
+
}
|
3012
|
+
}
|
3013
|
+
return out;
|
3014
|
+
},
|
3015
|
+
filterBy (x, k, value = undefined, out = []) {
|
3016
|
+
// description: https://github.com/ccxt/ccxt/blob/master/js/base/functions/generic.js
|
3017
|
+
for (const v of this.values (x)) {
|
3018
|
+
if (v[k] === value) {
|
3019
|
+
out.push (v);
|
3020
|
+
}
|
3021
|
+
}
|
3022
|
+
return out;
|
3023
|
+
},
|
3024
|
+
sortBy: (array, key, descending = false, direction = descending ? -1 : 1) => array.sort ((a, b) => {
|
3025
|
+
if (a[key] < b[key]) {
|
3026
|
+
return -direction;
|
3027
|
+
} else if (a[key] > b[key]) {
|
3028
|
+
return direction;
|
3029
|
+
} else {
|
3030
|
+
return 0;
|
3031
|
+
}
|
3032
|
+
}),
|
3033
|
+
sortBy2: (array, key1, key2, descending = false, direction = descending ? -1 : 1) => array.sort ((a, b) => {
|
3034
|
+
if (a[key1] < b[key1]) {
|
3035
|
+
return -direction;
|
3036
|
+
} else if (a[key1] > b[key1]) {
|
3037
|
+
return direction;
|
3038
|
+
} else {
|
3039
|
+
if (a[key2] < b[key2]) {
|
3040
|
+
return -direction;
|
3041
|
+
} else if (a[key2] > b[key2]) {
|
3042
|
+
return direction;
|
3043
|
+
} else {
|
3044
|
+
return 0;
|
3045
|
+
}
|
3046
|
+
}
|
3047
|
+
}),
|
3048
|
+
flatten: function flatten (x, out = []) {
|
3049
|
+
|
3050
|
+
for (const v of x) {
|
3051
|
+
if (this.isArray (v)) {
|
3052
|
+
this.flatten (v, out);
|
3053
|
+
} else {
|
3054
|
+
out.push (v);
|
3055
|
+
}
|
3056
|
+
}
|
3057
|
+
|
3058
|
+
return out;
|
3059
|
+
},
|
3060
|
+
pluck(x, k) { return this.values (x).filter ((v) => k in v).map ((v) => v[k]);},
|
3061
|
+
omit (x, ...args) {
|
3062
|
+
if (!Array.isArray (x)) {
|
3063
|
+
const out = this.clone (x);
|
3064
|
+
for (const k of args) {
|
3065
|
+
if (this.isArray (k)) { // omit (x, ['a', 'b'])
|
3066
|
+
for (const kk of k) {
|
3067
|
+
delete out[kk];
|
3068
|
+
}
|
3069
|
+
} else {
|
3070
|
+
delete out[k]; // omit (x, 'a', 'b')
|
3071
|
+
}
|
3072
|
+
}
|
3073
|
+
return out;
|
3074
|
+
}
|
3075
|
+
return x;
|
3076
|
+
},
|
3077
|
+
sum (...xs) {
|
3078
|
+
const ns = xs.filter (isNumber); // leave only numbers
|
3079
|
+
return (ns.length > 0) ? ns.reduce ((a, b) => a + b, 0) : undefined;
|
3080
|
+
},
|
3081
|
+
deepExtend: function deepExtend (...xs) {
|
3082
|
+
let out = undefined;
|
3083
|
+
for (const x of xs) {
|
3084
|
+
if (this.isDictionary (x)) {
|
3085
|
+
if (!this.isDictionary (out)) {
|
3086
|
+
out = {};
|
3087
|
+
}
|
3088
|
+
for (const k in x) { // eslint-disable-line guard-for-in
|
3089
|
+
out[k] = this.deepExtend (out[k], x[k]);
|
3090
|
+
}
|
3091
|
+
} else {
|
3092
|
+
out = x;
|
3093
|
+
}
|
3094
|
+
}
|
3095
|
+
return out;
|
3096
|
+
},
|
3097
|
+
// type
|
3098
|
+
isNumber: Number.isFinite,
|
3099
|
+
isInteger: Number.isInteger,
|
3100
|
+
isArray: Array.isArray,
|
3101
|
+
hasProps: o => ((o !== undefined) && (o !== null)),
|
3102
|
+
isString: s => (typeof s === 'string'),
|
3103
|
+
isObject: o => ((o !== null) && (typeof o === 'object')),
|
3104
|
+
isRegExp: o => (o instanceof RegExp),
|
3105
|
+
isDictionary(o ){return (this.isObject (o) && (Object.getPrototypeOf (o) === Object.prototype) && !isArray (o) && !isRegExp (o));},
|
3106
|
+
isStringCoercible(x){ return ((this.hasProps (x) && x.toString) || this.isNumber (x));},
|
3107
|
+
prop (o, k) { return (this.isObject (o) && o[k] !== '' && o[k] !== null ? o[k] : undefined);},
|
3108
|
+
getValueFromKeysInArray(object, array) { return object[array.find (k => this.prop (object,k) !== undefined)];},
|
3109
|
+
asFloat (x) { return ((this.isNumber (x) || (this.isString (x) && x.length !== 0)) ? parseFloat (x) : NaN);}
|
3110
|
+
,
|
3111
|
+
asInteger(x) { return ((this.isNumber (x) || (this.isString (x) && x.length !== 0)) ? Math.trunc (Number(x)) : NaN);},
|
3112
|
+
// safeFloat:(o, k, $default, n = asFloat (prop (o, k))) => (this.isNumber (n) ? n : $default),
|
3113
|
+
// safeInteger: (o, k, $default, n = asInteger (prop (o, k))) => (this.isNumber (n) ? n : $default),
|
3114
|
+
// safeTimestamp: (o, k, $default, n = asFloat (prop (o, k))) => (isNumber (n) ? parseInt (n * 1000) : $default),
|
3115
|
+
// safeValue(o, k, $default, x = prop (o, k)) { return (hasProps (x) ? x : $default); },
|
3116
|
+
// safeString(o, k, $default, x = prop (o, k)){ return (this.isStringCoercible (x) ? String (x) : $default);},
|
3117
|
+
// safeStringLower(o, k, $default, x = prop (o, k)){ return (this.isStringCoercible (x) ? String (x).toLowerCase () : $default ? $default.toLowerCase () : $default);},
|
3118
|
+
// safeStringUpper(o, k, $default, x = prop (o, k)){ return (this.isStringCoercible (x) ? String (x).toUpperCase () : $default ? $default.toUpperCase () : $default);},
|
3119
|
+
|
3120
|
+
// misc
|
3121
|
+
parseTimeframe(timeframe){
|
3122
|
+
const amount = timeframe.slice (0, -1);
|
3123
|
+
const unit = timeframe.slice (-1);
|
3124
|
+
let scale = undefined;
|
3125
|
+
if (unit === 'y') { scale = 60 * 60 * 24 * 365; }
|
3126
|
+
else if (unit === 'M') { scale = 60 * 60 * 24 * 30; }
|
3127
|
+
else if (unit === 'w') { scale = 60 * 60 * 24 * 7; }
|
3128
|
+
else if (unit === 'd') { scale = 60 * 60 * 24; }
|
3129
|
+
else if (unit === 'h') { scale = 60 * 60;}
|
3130
|
+
else if (unit === 'm') { scale = 60; }
|
3131
|
+
else if (unit === 's') { scale = 1; }
|
3132
|
+
else { throw new NotSupported ('timeframe unit ' + unit + ' is not supported'); }
|
3133
|
+
return amount * scale;
|
3134
|
+
},
|
3135
|
+
roundTimeframe(timeframe, timestamp, direction = ROUND_DOWN) {
|
3136
|
+
const ms = this.parseTimeframe (timeframe) * 1000
|
3137
|
+
// Get offset based on timeframe in milliseconds
|
3138
|
+
const offset = timestamp % ms
|
3139
|
+
return timestamp - offset + ((direction === ROUND_UP) ? ms : 0);
|
3140
|
+
},
|
3141
|
+
json:(data, params = undefined) => JSON.stringify (data),
|
3142
|
+
isJsonEncodedObject: object => (
|
3143
|
+
(typeof object === 'string') &&
|
3144
|
+
(object.length >= 2) &&
|
3145
|
+
((object[0] === '{') || (object[0] === '['))
|
3146
|
+
),
|
3147
|
+
// number
|
3148
|
+
precisionFromString (string) {
|
3149
|
+
const split = string.replace (/0+$/g, '').split ('.')
|
3150
|
+
return (split.length > 1) ? (split[1].length) : 0
|
3151
|
+
},
|
3152
|
+
numberToString (x) { // avoids scientific notation for too large and too small numbers
|
3153
|
+
if (x === undefined) return undefined; if (typeof x !== 'number') return x.toString (); const s = x.toString (); if (Math.abs (x) < 1.0) { const n_e = s.split ('e-'); const n = n_e[0].replace ('.', ''); const e = parseInt (n_e[1]); const neg = (s[0] === '-'); if (e) { x = (neg ? '-' : '') + '0.' + (new Array (e)).join ('0') + n.substring (neg); return x; } } else { const parts = s.split ('e'); if (parts[1]) { let e = parseInt (parts[1]); const m = parts[0].split ('.'); let part = ''; if (m[1]) { e -= m[1].length; part = m[1]; } return m[0] + part + (new Array (e + 1)).join ('0'); } } return s;
|
3154
|
+
},
|
3155
|
+
// platform
|
3156
|
+
isBrowser: typeof window !== 'undefined',
|
3157
|
+
isElectron: typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined',
|
3158
|
+
isWebWorker: typeof WorkerGlobalScope !== 'undefined' && (self instanceof WorkerGlobalScope),
|
3159
|
+
isWindows: typeof process !== 'undefined' && process.platform === "win32",
|
3160
|
+
isNode: !(this.isBrowser || this.isWebWorker),
|
3161
|
+
defaultFetch: fetch,
|
3162
|
+
//string
|
3163
|
+
uuid: a => a ? (a ^ Math.random () * 16 >> a / 4).toString (16) : ([1e7]+-1e3+-4e3+-8e3+-1e11).replace (/[018]/g, uuid),
|
3164
|
+
capitalize: s => s.length ? (s.charAt (0).toUpperCase () + s.slice (1)) : s,
|
3165
|
+
strip: s => s.replace(/^\s+|\s+$/g, ''),
|
3166
|
+
// time
|
3167
|
+
now: Date.now,
|
3168
|
+
milliseconds: Date.now, // milliseconds(){ return (new Date().getTime()); },
|
3169
|
+
seconds: () => Math.floor (Date.now () / 1000),
|
3170
|
+
// endregion: ####### from CCXT ##########
|
3171
|
+
|
3172
|
+
|
3173
|
+
|
3092
3174
|
};
|
3093
3175
|
|
3094
3176
|
|
package/package.json
CHANGED