@osimatic/helpers-js 1.0.2

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/network.js ADDED
@@ -0,0 +1,554 @@
1
+
2
+ class HTTPRequest {
3
+ static getHttpHeaders() {
4
+ if (!JwtSession.isAnonymous()) { //on ne définit pas ce header si on ne trouve pas d'access_token
5
+ httpHeaders['Authorization'] = 'Bearer ' + JwtSession.getToken();
6
+ }
7
+
8
+ return httpHeaders;
9
+ }
10
+
11
+ static async get(url, data, successCallback, errorCallback) {
12
+ if (data == null) {
13
+ data = '';
14
+ }
15
+ else if (typeof data == 'object') {
16
+ data = UrlAndQueryString.buildQuery(data);
17
+ }
18
+ if (data !== '' && data.substring(0, 1) !== '&') {
19
+ data = '&' + data;
20
+ }
21
+
22
+ if (window.fetch) {
23
+ let requestInit = {
24
+ method: 'GET',
25
+ headers: _httpHeaders,
26
+ mode: 'cors',
27
+ cache: 'no-cache'
28
+ }
29
+
30
+ let jsonData = {};
31
+ const response = await fetch(url + (!url.includes('?') ? '?' : '') + data, requestInit);
32
+ try {
33
+ jsonData = await response.json();
34
+ //console.log(url, jsonData);
35
+
36
+ if (response.status == 401 && response.statusText == "Expired JWT Token") {
37
+ HTTPRequest.refreshToken(URL_REFRESH, () => HTTPRequest.get(url, data, successCallback, errorCallback));
38
+ return;
39
+ }
40
+
41
+ if (response.ok) {
42
+ successCallback(jsonData);
43
+ return;
44
+ }
45
+ }
46
+ catch (e) {
47
+ errorCallback(response, response.status, e);
48
+ return;
49
+ }
50
+ errorCallback(response, response.status, null, jsonData);
51
+ return;
52
+ }
53
+
54
+ //l'api fetch n'est pas dispo pour ce navigateur => normalement ce cas ne devrait pas arriver car le polyfill est chargé
55
+ console.error('fetch\'s polyfill used');
56
+ $.ajax({
57
+ type: 'GET',
58
+ url: url + (!url.includes('?') ? '?' : '') + data,
59
+ headers: HTTPRequest.getHttpHeaders(),
60
+ dataType: 'json',
61
+ cache: false,
62
+ success: (data) => successCallback(data),
63
+ error: (jqxhr, status, exception) => {
64
+ if (typeof jqxhr.responseJSON != 'undefined' && jqxhr.responseJSON.code == 401 && jqxhr.responseJSON.message == "Expired JWT Token") {
65
+ HTTPRequest.refreshToken(URL_REFRESH, () => HTTPRequest.get(url, data, successCallback, errorCallback));
66
+ } else {
67
+ errorCallback(jqxhr, status, exception);
68
+ }
69
+ }
70
+ });
71
+ }
72
+
73
+ static async download(url, data, errorCallback, completeCallback) {
74
+ if (data == null) {
75
+ data = '';
76
+ }
77
+ else if (typeof data == 'object') {
78
+ data = UrlAndQueryString.buildQuery(data);
79
+ }
80
+ if (data !== '' && data.substring(0, 1) !== '&') {
81
+ data = '&' + data;
82
+ }
83
+
84
+
85
+ if (window.fetch) {
86
+ let requestInit = {
87
+ method: 'GET',
88
+ headers: _httpHeaders,
89
+ mode: 'cors',
90
+ cache: 'no-cache'
91
+ }
92
+
93
+ const response = await fetch(url + (!url.includes('?') ? '?' : '') + data, requestInit);
94
+ try {
95
+ const blobData = await response.blob();
96
+ /*console.log(url);
97
+ console.log(blobData);*/
98
+
99
+ if (response.status == 401 && response.statusText == "Expired JWT Token") {
100
+ HTTPRequest.refreshToken(URL_REFRESH, () => HTTPRequest.download(url, data, errorCallback, completeCallback));
101
+ return;
102
+ }
103
+
104
+ if (response.ok) {
105
+ File.download(blobData, response.headers.get('content-type'), response.headers.get('content-disposition'));
106
+ }
107
+ else if (typeof errorCallback != 'undefined' && errorCallback != null) {
108
+ errorCallback(response, response.status, null);
109
+ }
110
+ }
111
+ catch (e) {
112
+ if (typeof errorCallback != 'undefined' && errorCallback != null) {
113
+ errorCallback(response, response.status, e);
114
+ }
115
+ }
116
+ if (typeof completeCallback != 'undefined' && completeCallback != null) {
117
+ completeCallback(response, response.status);
118
+ }
119
+ return;
120
+ }
121
+
122
+ //l'api fetch n'est pas dispo pour ce navigateur => normalement ce cas ne devrait pas arriver car le polyfill est chargé
123
+ console.error('fetch\'s polyfill used');
124
+ $.ajax({
125
+ type: 'GET',
126
+ url: url + (!url.includes('?') ? '?' : '') + data,
127
+ headers: HTTPRequest.getHttpHeaders(),
128
+ cache: false,
129
+ xhrFields: {
130
+ responseType: 'blob'
131
+ },
132
+ success: (data, status, jqxhr) => File.download(data, jqxhr.getResponseHeader('Content-Type'), jqxhr.getResponseHeader('Content-Disposition')),
133
+ error: (jqxhr, status, exception) => {
134
+ if (typeof jqxhr.responseJSON != 'undefined' && jqxhr.responseJSON.code == 401 && jqxhr.responseJSON.message == "Expired JWT Token") {
135
+ HTTPRequest.refreshToken(URL_REFRESH, () => HTTPRequest.download(url, data, errorCallback, completeCallback));
136
+ } else if (typeof errorCallback != 'undefined' && errorCallback != null) {
137
+ errorCallback(jqxhr, status, exception);
138
+ }
139
+ },
140
+ complete: (jqxhr, status) => {
141
+ if (typeof completeCallback != 'undefined' && completeCallback != null) {
142
+ completeCallback(jqxhr, status);
143
+ }
144
+ }
145
+ });
146
+ }
147
+
148
+ static async post(url, formData, successCallback, errorCallback, formErrorCallback) {
149
+ if (window.fetch && false) {
150
+ let requestInit = {
151
+ method: 'POST',
152
+ body: formData,
153
+ headers: _httpHeaders,
154
+ mode: 'cors',
155
+ cache: 'no-cache'
156
+ };
157
+
158
+ let jsonData = {};
159
+ const response = await fetch(url, requestInit);
160
+
161
+ try {
162
+ jsonData = await response.json();
163
+ //console.log(url, jsonData);
164
+
165
+ if (response.status == 401 && response.statusText == "Expired JWT Token") {
166
+ HTTPRequest.refreshToken(URL_REFRESH, () => HTTPRequest.post(url, formData, successCallback, errorCallback, formErrorCallback));
167
+ return;
168
+ }
169
+
170
+ if (response.ok) {
171
+ successCallback(jsonData);
172
+ return;
173
+ }
174
+
175
+ if (response.status == 400 && typeof formErrorCallback != 'undefined' && formErrorCallback != null) {
176
+ formErrorCallback(response, response.status, jsonData);
177
+ return;
178
+ }
179
+ }
180
+ catch (e) {
181
+ errorCallback(response, response.status, e);
182
+ return;
183
+ }
184
+
185
+ errorCallback(response, response.status, null, jsonData);
186
+ return;
187
+ }
188
+
189
+ //l'api fetch n'est pas dispo pour ce navigateur => normalement ce cas ne devrait pas arriver car le polyfill est chargé
190
+ console.error('fetch\'s polyfill used');
191
+ $.ajax({
192
+ type: 'POST',
193
+ url: url,
194
+ headers: HTTPRequest.getHttpHeaders(),
195
+ dataType: 'json', // 22/09/2020 : à voir si cette ligne pose pb (utilisé pour requete import et peut être d'autres
196
+ data: formData,
197
+ cache: false,
198
+ contentType: false,
199
+ processData: false,
200
+ success: (data) => successCallback(data),
201
+ error: (jqxhr, status, exception) => {
202
+ if (typeof jqxhr.responseJSON != 'undefined' && jqxhr.responseJSON.code == 401 && jqxhr.responseJSON.message == "Expired JWT Token") {
203
+ HTTPRequest.refreshToken(URL_REFRESH, () => HTTPRequest.post(url, formData, successCallback, errorCallback, formErrorCallback));
204
+ } else if (jqxhr.status == 400 && typeof formErrorCallback != 'undefined' && formErrorCallback != null) {
205
+ formErrorCallback(jqxhr, status, exception);
206
+ } else {
207
+ errorCallback(jqxhr, status, exception);
208
+ }
209
+ }
210
+ });
211
+ }
212
+
213
+ static refreshToken(url, onCompleteCallback) {
214
+ let payload = new FormData();
215
+ payload.append('refresh_token', JwtSession.getRefreshToken());
216
+
217
+ HTTPRequest.post(url, payload,
218
+ (data) => {
219
+ JwtSession.setToken(data.token);
220
+ JwtSession.setRefreshToken(data.refresh_token);
221
+ onCompleteCallback();
222
+ }, (jqxhr, status, exception) => {
223
+ console.log(exception);
224
+ JwtSession.logout();
225
+ }
226
+ );
227
+ }
228
+
229
+ static doRequest(url, strParam, methode, formatRetour, callback) {
230
+ var xhr = null;
231
+
232
+ if (window.XMLHttpRequest || window.ActiveXObject) {
233
+ if (window.ActiveXObject) {
234
+ try {
235
+ xhr = new ActiveXObject('Msxml2.XMLHTTP');
236
+ } catch (e) {
237
+ xhr = new ActiveXObject('Microsoft.XMLHTTP');
238
+ }
239
+ } else {
240
+ xhr = new XMLHttpRequest();
241
+ }
242
+ } else {
243
+ // Votre navigateur ne supporte pas l'objet XMLHTTPRequest!
244
+ return null;
245
+ }
246
+
247
+ xhr.onreadystatechange = function () {
248
+ if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
249
+ if (formatRetour == 'xml') {
250
+ var data = xhr.responseXML;
251
+ }
252
+ else {
253
+ var data = eval('(' + xhr.responseText + ')');
254
+ }
255
+ callback(data);
256
+ }
257
+ };
258
+
259
+ if (methode === 'POST') {
260
+ xhr.open('POST', url, true);
261
+ xhr.send();
262
+ }
263
+ else {
264
+ xhr.open('GET', url + '?' + strParam, true);
265
+ xhr.send(null);
266
+ }
267
+ return false;
268
+ }
269
+ }
270
+
271
+ class Cookie {
272
+ static set(cname, cvalue, exdays) {
273
+ var d = new Date();
274
+ d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
275
+ var expires = "expires=" + d.toUTCString();
276
+ document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
277
+ }
278
+
279
+ static get(cname) {
280
+ var name = cname + "=";
281
+ var decodedCookie = decodeURIComponent(document.cookie);
282
+ var ca = decodedCookie.split(';');
283
+ for (var i = 0; i < ca.length; i++) {
284
+ var c = ca[i];
285
+ while (c.charAt(0) == ' ') {
286
+ c = c.substring(1);
287
+ }
288
+ if (c.indexOf(name) === 0) {
289
+ return c.substring(name.length, c.length);
290
+ }
291
+ }
292
+ return null;
293
+ }
294
+
295
+ static erase(name) {
296
+ Cookie.set(name, "", -1);
297
+ }
298
+ }
299
+
300
+ class UrlAndQueryString {
301
+ static getPath(url) {
302
+ if (typeof url == 'undefined') {
303
+ return window.location.origin + window.location.pathname;
304
+ }
305
+ let strpos = url.indexOf('?');
306
+ // Si on ne trouve pas de queryString on retourne une chaine vide
307
+ if (strpos === -1) {
308
+ return url;
309
+ }
310
+ return url.substr(0, strpos);
311
+ }
312
+
313
+ static getQueryString(url) {
314
+ if (typeof url == 'undefined') {
315
+ return window.location.search;
316
+ }
317
+ let urlObj = new URL(url);
318
+ return urlObj.search;
319
+ }
320
+
321
+ static getParam(key, url) {
322
+ var searchParams = new URLSearchParams(UrlAndQueryString.getQueryString(url));
323
+ return searchParams.get(key);
324
+ }
325
+
326
+ static setParam(queryString, name, value) {
327
+ // cette solution ne fonctionne pas avec les tableau
328
+ //let params = new URLSearchParams(queryString);
329
+ //params.set(name, value);
330
+ //return params.toString();
331
+
332
+ let params = UrlAndQueryString.parseQuery(queryString);
333
+ //console.log(params);
334
+ params[name] = value;
335
+ return decodeURI($.param(params));
336
+ }
337
+ static setParamOfUrl(name, value, url) {
338
+ let queryString = UrlAndQueryString.setParam(UrlAndQueryString.getQueryString(url), name, value);
339
+ return UrlAndQueryString.getPath(url) + '?' + queryString;
340
+ }
341
+
342
+ static deleteParam(queryString, name) {
343
+ let params = new URLSearchParams(queryString);
344
+ params.delete(name);
345
+ return decodeURI(params.toString());
346
+
347
+ //let params = UrlAndQueryString.parseQuery(queryString);
348
+ //params[name] = null;
349
+ //return $.param(params);
350
+ }
351
+ static deleteParamOfUrl(name, url) {
352
+ let queryString = UrlAndQueryString.deleteParam(UrlAndQueryString.getQueryString(url), name);
353
+ return UrlAndQueryString.getPath(url) + '?' + queryString;
354
+ }
355
+
356
+ static parseQuery(queryString) {
357
+ var params = {};
358
+
359
+ function buildParamFromString(param) {
360
+ var p = decodeURIComponent(param);
361
+ var strpos = p.indexOf('=');
362
+ // Si on trouve pas de signe =, on met la valeur ''
363
+ if (strpos === -1) {
364
+ params[p] = '';
365
+ //params.length++;
366
+ return true;
367
+ }
368
+ var name = p.substr(0, strpos);
369
+ var value = p.substr(strpos + 1, p.length);
370
+ var openBracket = name.indexOf('[');
371
+ var closeBracket = name.indexOf(']');
372
+ // On traite les paramètre qui ne sont pas sous forme de tableau
373
+ if (openBracket === -1 || closeBracket === -1) {
374
+ if (!(openBracket === -1 && closeBracket === -1)) {
375
+ name = name.replace(new RegExp('[\\[\\]]'), '_');
376
+ }
377
+ params[name] = value;
378
+ return true;
379
+ }
380
+ var matches = name.match(new RegExp('\\[.*?\\]', 'g'));
381
+ name = name.substr(0, openBracket);
382
+ p = 'params';
383
+ var key = name;
384
+ for (let i in matches) {
385
+ if (typeof (matches[i]) == 'function') {
386
+ continue;
387
+ }
388
+
389
+ p += '[\'' + key + '\']';
390
+ if (eval(p) == undefined || typeof (eval(p)) != 'object') {
391
+ eval(p + '= new Array();');
392
+ }
393
+ key = matches[i].substr(1, matches[i].length - 2);
394
+ // si la clé est null on met la longueur du tableau
395
+ if (key == '') {
396
+ key = eval(p).length;
397
+ }
398
+
399
+ /*
400
+ p += '[\''+key+'\']';
401
+ if(eval(p) == undefined || typeof(eval(p)) != 'object') {
402
+ eval(p +'= new Array();');
403
+ }
404
+ if (typeof(matches[i]) != 'function') {
405
+ key = matches[i].substr(1,matches[i].length-2);
406
+ // si la clé est null on met la longueur du tableau
407
+ if (key == '') {
408
+ key = eval(p).length;
409
+ }
410
+ }
411
+ else {
412
+ key = eval(p).length;
413
+ }
414
+ */
415
+ }
416
+ p += '[\'' + key + '\']';
417
+ eval(p + '= \'' + value + '\';');
418
+ }
419
+
420
+ var str = queryString;
421
+ if (str.includes('?')) {
422
+ str = str.substring(1);
423
+ }
424
+ if (str === '') {
425
+ return {};
426
+ }
427
+ str = str.replace(new RegExp('&'), '&');
428
+ //params.length = 0;
429
+ str = str.split('&');
430
+ //var p = '';
431
+ //var startPos = -1;
432
+ //var endPos = -1;
433
+ //var arrayName = '';
434
+ //var arrayKey = '';
435
+ for (let i = 0; i < str.length; i++) {
436
+ buildParamFromString(str[i]);
437
+ }
438
+ // return JSON.parse(JSON.stringify(this.params));
439
+ return params;
440
+ }
441
+
442
+ static buildQuery(object) {
443
+ var params = [];
444
+
445
+ function buildStringFromParam(object, prefix) {
446
+ var p = '';
447
+ var value = '';
448
+ if (prefix !== undefined) {
449
+ p = prefix;
450
+ }
451
+ if (typeof (object) == 'object') {
452
+ for (var name in object) {
453
+ value = object[name];
454
+ // 14/01/2020 : les tableaux avec param[0], param[1] en query string fonctionne pas, il faut mettre param[]=x&param[]=y
455
+ //name = p == '' ? name : '['+name+']';
456
+ name = p == '' ? name : '[]';
457
+ if (typeof (value) == 'object') {
458
+ buildStringFromParam(value, p + name);
459
+ }
460
+ else if (typeof (value) != 'function' && name != '') {
461
+ // 27/01/2020 : correction bug boolean affiché en string true/false
462
+ if (typeof (value) == 'boolean') {
463
+ value = (value ? 1 : 0);
464
+ }
465
+ params[params.length] = p + name + '=' + value;
466
+ }
467
+ }
468
+ }
469
+ }
470
+
471
+ buildStringFromParam(object);
472
+ return params.join('&');
473
+ }
474
+
475
+
476
+
477
+
478
+
479
+
480
+
481
+
482
+
483
+
484
+
485
+
486
+
487
+
488
+
489
+
490
+
491
+
492
+
493
+ // deprecated
494
+
495
+ static parseQueryString(string) {
496
+ if (string === "" || string == null) return {};
497
+ if (string.charAt(0) === "?") string = string.slice(1);
498
+ var entries = string.split("&"), counters = {}, data0 = {};
499
+ for (var i = 0; i < entries.length; i++) {
500
+ var entry = entries[i].split("=");
501
+ var key5 = decodeURIComponent(entry[0]);
502
+ var value2 = entry.length === 2 ? decodeURIComponent(entry[1]) : "";
503
+ if (value2 === "true") value2 = true;
504
+ else if (value2 === "false") value2 = false;
505
+ var levels = key5.split(/\]\[?|\[/);
506
+ var cursor = data0;
507
+ if (key5.indexOf("[") > -1) levels.pop();
508
+ for (var j0 = 0; j0 < levels.length; j0++) {
509
+ var level = levels[j0], nextLevel = levels[j0 + 1];
510
+ var isNumber = nextLevel == "" || !isNaN(parseInt(nextLevel, 10));
511
+ if (level === "") {
512
+ var key5 = levels.slice(0, j0).join();
513
+ if (counters[key5] == null) {
514
+ counters[key5] = Array.isArray(cursor) ? cursor.length : 0;
515
+ }
516
+ level = counters[key5]++;
517
+ }
518
+ // Disallow direct prototype pollution
519
+ else if (level === "__proto__") break;
520
+ if (j0 === levels.length - 1) cursor[level] = value2;
521
+ else {
522
+ // Read own properties exclusively to disallow indirect
523
+ // prototype pollution
524
+ var desc = Object.getOwnPropertyDescriptor(cursor, level);
525
+ if (desc != null) desc = desc.value;
526
+ if (desc == null) cursor[level] = desc = isNumber ? [] : {};
527
+ cursor = desc;
528
+ }
529
+ }
530
+ }
531
+ return data0;
532
+ }
533
+
534
+ static getQuery(url) {
535
+ var str = url;
536
+ var strpos = str.indexOf('?');
537
+ // Si on ne trouve pas de queryString on retourne une chaine vide
538
+ if (strpos === -1) {
539
+ return '';
540
+ }
541
+ str = str.substr(strpos + 1, str.length);
542
+ // Maintenant on verifie si on a une anchor ou pas (#) et si c'est le cas on arrete la querystring avant
543
+ strpos = str.indexOf('#');
544
+ if (strpos === -1) {
545
+ return str;
546
+ }
547
+ return str.substr(0, strpos);
548
+ }
549
+
550
+ }
551
+
552
+ exports.HTTPRequest = HTTPRequest;
553
+ exports.Cookie = Cookie;
554
+ exports.UrlAndQueryString = UrlAndQueryString;
package/number.js ADDED
@@ -0,0 +1,90 @@
1
+
2
+ class NumberValue {
3
+ static isNumeric(sText) {
4
+ var ValidChars = "0123456789.";
5
+ var IsNumber=true;
6
+ var Char;
7
+ for (i = 0; i < sText.length && IsNumber == true; i++){
8
+ Char = sText.charAt(i);
9
+ if (ValidChars.indexOf(Char) == -1){
10
+ IsNumber = false;
11
+ }
12
+ }
13
+ return IsNumber;
14
+ }
15
+
16
+ static format(number, nbDecimal, locale) {
17
+ nbDecimal = (typeof nbDecimal != 'undefined'?nbDecimal:2);
18
+ return new Intl.NumberFormat(locale, {
19
+ minimumFractionDigits: nbDecimal,
20
+ maximumFractionDigits: nbDecimal
21
+ }).format(number);
22
+ }
23
+
24
+ static formatCurrency(montant, currency, nbDecimal, locale) {
25
+ nbDecimal = (typeof nbDecimal != 'undefined'?nbDecimal:2);
26
+ return new Intl.NumberFormat(locale, {
27
+ style: 'currency',
28
+ currency: currency,
29
+ minimumFractionDigits: nbDecimal,
30
+ maximumFractionDigits: nbDecimal
31
+ }).format(montant);
32
+ }
33
+
34
+ static formatPercent(number, nbDecimal, locale) {
35
+ nbDecimal = (typeof nbDecimal != 'undefined'?nbDecimal:2);
36
+ return new Intl.NumberFormat(locale, {
37
+ style: 'percent',
38
+ minimumFractionDigits: nbDecimal,
39
+ maximumFractionDigits: nbDecimal
40
+ }).format(number);
41
+ }
42
+
43
+ static random(min, max) {
44
+ return Math.floor(Math.random() * (max - min + 1)) + min;
45
+ }
46
+
47
+ static padLeft2(n) {
48
+ return n > 9 ? "" + n: "0" + n;
49
+ }
50
+
51
+ static roundDecimal(nombre, precision) {
52
+ precision = precision || 2;
53
+ var tmp = Math.pow(10, precision);
54
+ return Math.round(nombre*tmp) / tmp;
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Number.prototype.format(n, x, s, c)
60
+ *
61
+ * @param integer n: length of decimal
62
+ * @param mixed s: sections delimiter
63
+ * @param mixed c: decimal delimiter
64
+ * @param integer x: length of sections
65
+ */
66
+ Number.prototype.formatForDisplay = function(n, s, c, x) {
67
+ var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\D' : '$') + ')',
68
+ num = this.toFixed(Math.max(0, ~~n));
69
+ return (c ? num.replace('.', c) : num).replace(new RegExp(re, 'g'), '$&' + (s || ','));
70
+ };
71
+
72
+ Number.prototype.formatAsString = function(locale, minimumFractionDigits) {
73
+ minimumFractionDigits = (typeof minimumFractionDigits != 'undefined'?minimumFractionDigits:0);
74
+ return new Intl.NumberFormat(locale, {minimumFractionDigits: minimumFractionDigits}).format(this);
75
+ };
76
+
77
+ Number.prototype.formatAsCurrency = function(locale, currency, nbFractionDigits) {
78
+ nbFractionDigits = (typeof nbFractionDigits != 'undefined'?nbFractionDigits:2);
79
+ return new Intl.NumberFormat(locale, {
80
+ style: 'currency',
81
+ currency: 'EUR',
82
+ minimumFractionDigits: nbFractionDigits,
83
+ maximumFractionDigits: nbFractionDigits
84
+ }).format(this);
85
+ };
86
+
87
+ Number.prototype.formatAsPercent = function(locale, minimumFractionDigits) {
88
+ minimumFractionDigits = (typeof minimumFractionDigits != 'undefined'?minimumFractionDigits:0);
89
+ return new Intl.NumberFormat(locale, {style: 'percent', minimumFractionDigits:minimumFractionDigits}).format(this);
90
+ };
package/package.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "@osimatic/helpers-js",
3
+ "version": "1.0.2",
4
+ "main": "index.js",
5
+ "scripts": {
6
+ "test": "echo \"Error: no test specified\" && exit 1"
7
+ },
8
+ "keywords": [],
9
+ "author": "",
10
+ "license": "ISC",
11
+ "description": ""
12
+ }