@osimatic/helpers-js 1.4.28 → 1.5.0

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/README CHANGED
@@ -1 +1,2 @@
1
- npm install @osimatic/helpers-js
1
+ npm install @osimatic/helpers-js
2
+ browserify index.js -o index.bundle.js
package/bank.js CHANGED
@@ -1,3 +1,5 @@
1
+ const { SqlDateTime } = require('./date_time');
2
+
1
3
  class IBAN {
2
4
  static format(iban) {
3
5
  return iban.toUpperCase().replace(/[^\dA-Z]/g, '').replace(/(.{4})/g, '$1 ').trim();
@@ -1,4 +1,7 @@
1
1
 
2
+ const libphonenumber = require('libphonenumber-js/max');
3
+ const { Country } = require('./location');
4
+
2
5
  class PersonName {
3
6
 
4
7
  static format(firstName, lastName) {
@@ -48,8 +51,6 @@ class Email {
48
51
  }
49
52
 
50
53
  class TelephoneNumber {
51
- //this class works with libphonenumber-max.min.js
52
-
53
54
  static setLocalCountryCode(countryCode) {
54
55
  TelephoneNumber.localCountryCode = countryCode;
55
56
  }
package/date_time.js CHANGED
@@ -1,4 +1,6 @@
1
1
 
2
+ require('./string');
3
+
2
4
  class DateTimeFormatter {
3
5
  static getDateDigitalFormatter(locale, timeZone) {
4
6
  this.dateDigitalFormatter = this.dateDigitalFormatter || {};
package/location.js CHANGED
@@ -1,4 +1,7 @@
1
1
 
2
+ const Address = require('ilib/lib/Address');
3
+ const AddressFmt = require('ilib/lib/AddressFmt');
4
+
2
5
  class Country {
3
6
  static setFlagsPath(flagsPath) {
4
7
  Country.flagsPath = flagsPath;
@@ -356,9 +359,6 @@ class PostalAddress {
356
359
  addressDataForPluging['locality'] = addressData['stateDistrict'];
357
360
  }
358
361
 
359
- //var Address = require("ilib/js/lib/Address");
360
- //var AddressFmt = require("ilib/lib/AddressFmt");
361
-
362
362
  let af = new AddressFmt();
363
363
  let formattedAddress = af.format(new Address(addressDataForPluging));
364
364
  return formattedAddress.replace(/\n+/g, separator);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@osimatic/helpers-js",
3
- "version": "1.4.28",
3
+ "version": "1.5.0",
4
4
  "main": "main.js",
5
5
  "scripts": {
6
6
  "test": "jest",
@@ -13,7 +13,13 @@
13
13
  "license": "ISC",
14
14
  "description": "",
15
15
  "dependencies": {
16
- "ilib": "^14.16.0"
16
+ "ilib": "^14.21",
17
+ "libphonenumber-js": "^1.12.39",
18
+ "ua-parser-js": "^2.0.9"
19
+ },
20
+ "peerDependencies": {
21
+ "intl-tel-input": ">=19.0",
22
+ "leaflet": ">=1.9"
17
23
  },
18
24
  "devDependencies": {
19
25
  "jest": "^30.2.0",
@@ -108,50 +108,26 @@ describe('BankCard', () => {
108
108
  });
109
109
 
110
110
  describe('formatExpirationDate', () => {
111
- // Mock SqlDateTime since it's imported from another module
112
- beforeAll(() => {
113
- global.SqlDateTime = {
114
- getMonthName: jest.fn((date, locale) => {
115
- // Mock implementation
116
- const d = new Date(date);
117
- const month = d.toLocaleString(locale, { month: 'long' });
118
- return month.charAt(0).toUpperCase() + month.slice(1);
119
- }),
120
- getYear: jest.fn((date) => {
121
- const d = new Date(date);
122
- return d.getFullYear();
123
- })
124
- };
125
- });
126
-
127
- afterAll(() => {
128
- delete global.SqlDateTime;
129
- });
130
-
131
111
  test('should format expiration date in French', () => {
132
- const date = '2025-12-31';
133
- const result = BankCard.formatExpirationDate(date, 'fr-FR');
112
+ const result = BankCard.formatExpirationDate('2025-12-31', 'fr-FR');
134
113
  expect(result).toContain('2025');
135
- expect(SqlDateTime.getMonthName).toHaveBeenCalledWith(date, 'fr-FR');
136
- expect(SqlDateTime.getYear).toHaveBeenCalledWith(date);
114
+ expect(result).toContain('décembre');
137
115
  });
138
116
 
139
117
  test('should use default locale fr-FR', () => {
140
- const date = '2025-06-15';
141
- BankCard.formatExpirationDate(date);
142
- expect(SqlDateTime.getMonthName).toHaveBeenCalledWith(date, 'fr-FR');
118
+ const result = BankCard.formatExpirationDate('2025-06-15');
119
+ expect(result).toContain('2025');
120
+ expect(result).toContain('juin');
143
121
  });
144
122
 
145
123
  test('should format expiration date in English', () => {
146
- const date = '2025-03-20';
147
- const result = BankCard.formatExpirationDate(date, 'en-US');
124
+ const result = BankCard.formatExpirationDate('2025-03-20', 'en-US');
148
125
  expect(result).toContain('2025');
149
- expect(SqlDateTime.getMonthName).toHaveBeenCalledWith(date, 'en-US');
126
+ expect(result).toContain('March');
150
127
  });
151
128
 
152
129
  test('should handle different date formats', () => {
153
- const date = '2026-01-01';
154
- const result = BankCard.formatExpirationDate(date);
130
+ const result = BankCard.formatExpirationDate('2026-01-01');
155
131
  expect(result).toContain('2026');
156
132
  });
157
133
  });
@@ -171,51 +171,6 @@ describe('Email', () => {
171
171
  });
172
172
 
173
173
  describe('TelephoneNumber', () => {
174
- // Mock libphonenumber
175
- beforeAll(() => {
176
- global.libphonenumber = {
177
- parsePhoneNumber: jest.fn((phoneNumber, countryCode) => {
178
- // Simple mock implementation
179
- if (phoneNumber === '+33612345678') {
180
- return {
181
- country: 'FR',
182
- formatNational: () => '06 12 34 56 78',
183
- formatInternational: () => '+33 6 12 34 56 78',
184
- isValid: () => true,
185
- getType: () => 'MOBILE'
186
- };
187
- }
188
- if (phoneNumber === '+14155552671') {
189
- return {
190
- country: 'US',
191
- formatNational: () => '(415) 555-2671',
192
- formatInternational: () => '+1 415-555-2671',
193
- isValid: () => true,
194
- getType: () => 'FIXED_LINE_OR_MOBILE'
195
- };
196
- }
197
- if (phoneNumber === 'invalid') {
198
- throw new Error('Invalid phone number');
199
- }
200
- return null;
201
- })
202
- };
203
-
204
- global.Country = {
205
- getCountryName: jest.fn((code) => {
206
- const countries = { FR: 'France', US: 'United States' };
207
- return countries[code] || code;
208
- }),
209
- getFlagImg: jest.fn((code) => {
210
- return `<img src="/flags/${code.toLowerCase()}.png" />`;
211
- })
212
- };
213
- });
214
-
215
- afterAll(() => {
216
- delete global.libphonenumber;
217
- delete global.Country;
218
- });
219
174
 
220
175
  describe('setLocalCountryCode', () => {
221
176
  test('should set local country code', () => {
@@ -360,22 +315,21 @@ describe('TelephoneNumber', () => {
360
315
  test('should return country name for phone number', () => {
361
316
  const result = TelephoneNumber.getCountryName('+33612345678', 'FR');
362
317
  expect(result).toBe('France');
363
- expect(Country.getCountryName).toHaveBeenCalledWith('FR');
364
318
  });
365
319
  });
366
320
 
367
321
  describe('getFlagImg', () => {
368
322
  test('should return flag image for phone number', () => {
369
323
  const result = TelephoneNumber.getFlagImg('+33612345678', 'FR');
370
- expect(result).toContain('<img src="/flags/fr.png"');
371
- expect(Country.getFlagImg).toHaveBeenCalledWith('FR');
324
+ expect(result).toContain('fr.png');
325
+ expect(result).toContain('<img');
372
326
  });
373
327
  });
374
328
 
375
329
  describe('formatNationalWithFlagImg', () => {
376
330
  test('should format phone number with flag image', () => {
377
331
  const result = TelephoneNumber.formatNationalWithFlagImg('+33612345678', 'FR');
378
- expect(result).toContain('<img src="/flags/fr.png"');
332
+ expect(result).toContain('fr.png');
379
333
  expect(result).toContain('06 12 34 56 78');
380
334
  });
381
335
  });
@@ -383,7 +337,7 @@ describe('TelephoneNumber', () => {
383
337
  describe('formatNationalWithFlagImgAndTelLink', () => {
384
338
  test('should format phone number with flag and tel link', () => {
385
339
  const result = TelephoneNumber.formatNationalWithFlagImgAndTelLink('+33612345678', 'FR');
386
- expect(result).toContain('<img src="/flags/fr.png"');
340
+ expect(result).toContain('fr.png');
387
341
  expect(result).toContain('<a href="tel:+33612345678">');
388
342
  expect(result).toContain('06 12 34 56 78');
389
343
  });
@@ -81,13 +81,6 @@ describe('DatePeriod', () => {
81
81
  });
82
82
 
83
83
  describe('getPeriodLabels', () => {
84
- beforeAll(() => {
85
- // Mock capitalize sur String
86
- String.prototype.capitalize = function() {
87
- return this.charAt(0).toUpperCase() + this.slice(1);
88
- };
89
- });
90
-
91
84
  test('should return empty array for empty data', () => {
92
85
  expect(DatePeriod.getPeriodLabels([], 'day')).toEqual([]);
93
86
  expect(DatePeriod.getPeriodLabels(null, 'day')).toEqual([]);
@@ -1,4 +1,4 @@
1
- const { Country, GeographicCoordinates, Polygon } = require('../location');
1
+ const { Country, PostalAddress, GeographicCoordinates, Polygon } = require('../location');
2
2
 
3
3
  describe('Country', () => {
4
4
  describe('getCountries', () => {
@@ -592,4 +592,119 @@ describe('Polygon', () => {
592
592
  expect(lastPoint).toEqual(firstPoint);
593
593
  });
594
594
  });
595
+ });
596
+
597
+ describe('PostalAddress', () => {
598
+ describe('format', () => {
599
+ test('should return a string', () => {
600
+ const result = PostalAddress.format({
601
+ streetAddress: '10 Rue de la Paix',
602
+ postalCode: '75001',
603
+ locality: 'Paris',
604
+ countryCode: 'FR',
605
+ });
606
+ expect(typeof result).toBe('string');
607
+ });
608
+
609
+ test('should contain streetAddress, postalCode and locality', () => {
610
+ const result = PostalAddress.format({
611
+ streetAddress: '10 Rue de la Paix',
612
+ postalCode: '75001',
613
+ locality: 'Paris',
614
+ countryCode: 'FR',
615
+ });
616
+ expect(result).toContain('10 Rue de la Paix');
617
+ expect(result).toContain('75001');
618
+ expect(result).toContain('Paris');
619
+ });
620
+
621
+ test('should use <br/> as default separator', () => {
622
+ const result = PostalAddress.format({
623
+ streetAddress: '10 Rue de la Paix',
624
+ postalCode: '75001',
625
+ locality: 'Paris',
626
+ countryCode: 'FR',
627
+ });
628
+ expect(result).toContain('<br/>');
629
+ expect(result).not.toContain('\n');
630
+ });
631
+
632
+ test('should use custom separator when provided', () => {
633
+ const result = PostalAddress.format({
634
+ streetAddress: '10 Rue de la Paix',
635
+ postalCode: '75001',
636
+ locality: 'Paris',
637
+ countryCode: 'FR',
638
+ }, ', ');
639
+ expect(result).toContain(', ');
640
+ expect(result).not.toContain('\n');
641
+ });
642
+
643
+ test('should include additionalAddress on a separate line', () => {
644
+ const result = PostalAddress.format({
645
+ streetAddress: '10 Rue de la Paix',
646
+ additionalAddress: 'Bât. B',
647
+ postalCode: '75001',
648
+ locality: 'Paris',
649
+ countryCode: 'FR',
650
+ });
651
+ expect(result).toContain('10 Rue de la Paix');
652
+ expect(result).toContain('Bât. B');
653
+ });
654
+
655
+ test('should use suburb as locality fallback when locality is null', () => {
656
+ const result = PostalAddress.format({
657
+ streetAddress: '5 High Street',
658
+ postalCode: 'SW1A 1AA',
659
+ suburb: 'Westminster',
660
+ countryCode: 'GB',
661
+ });
662
+ expect(result).toContain('Westminster');
663
+ });
664
+
665
+ test('should use stateDistrict as locality fallback when locality and suburb are null', () => {
666
+ const result = PostalAddress.format({
667
+ streetAddress: '5 High Street',
668
+ postalCode: 'SW1A 1AA',
669
+ stateDistrict: 'Greater London',
670
+ countryCode: 'GB',
671
+ });
672
+ expect(result).toContain('Greater London');
673
+ });
674
+
675
+ test('should handle null/undefined optional fields without throwing', () => {
676
+ expect(() => PostalAddress.format({
677
+ streetAddress: null,
678
+ additionalAddress: null,
679
+ postalCode: null,
680
+ locality: null,
681
+ state: null,
682
+ countryCode: null,
683
+ })).not.toThrow();
684
+ });
685
+
686
+ test('should handle empty strings for optional fields', () => {
687
+ expect(() => PostalAddress.format({
688
+ streetAddress: '',
689
+ additionalAddress: '',
690
+ postalCode: '',
691
+ locality: '',
692
+ state: '',
693
+ countryCode: '',
694
+ })).not.toThrow();
695
+ });
696
+
697
+ test('should include state/region in the formatted address', () => {
698
+ const result = PostalAddress.format({
699
+ streetAddress: '1600 Amphitheatre Pkwy',
700
+ locality: 'Mountain View',
701
+ state: 'CA',
702
+ postalCode: '94043',
703
+ countryCode: 'US',
704
+ });
705
+ expect(result).toContain('CA');
706
+ expect(result).toContain('Mountain View');
707
+ expect(result).toContain('94043');
708
+ });
709
+ });
595
710
  });
@@ -244,114 +244,31 @@ describe('UserAgent', () => {
244
244
  });
245
245
 
246
246
  describe('getData', () => {
247
- test('should return null when UAParser is undefined', () => {
248
- expect(UserAgent.getData('some user agent')).toBeNull();
249
- });
250
-
251
- test('should parse user agent when UAParser is defined', () => {
252
- global.UAParser = jest.fn(() => ({
253
- os: { name: 'Windows', version: '10' },
254
- browser: { name: 'Chrome', major: '91' },
255
- device: { type: 'desktop', vendor: 'Dell', model: 'Inspiron' }
256
- }));
257
-
258
- const result = UserAgent.getData('Mozilla/5.0...');
259
-
260
- expect(result).toEqual({
261
- os: 'Windows 10',
262
- browser: 'Chrome 91',
263
- device: 'desktop Dell Inspiron'
264
- });
265
-
266
- delete global.UAParser;
247
+ test('should parse Windows Chrome user agent', () => {
248
+ const ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36';
249
+ const result = UserAgent.getData(ua);
250
+ expect(result.os).toBe('Windows 10');
251
+ expect(result.browser).toBe('Chrome 91');
252
+ expect(result.device).toBeNull();
267
253
  });
268
254
 
269
255
  test('should handle os without version', () => {
270
- global.UAParser = jest.fn(() => ({
271
- os: { name: 'Linux' },
272
- browser: { name: 'Firefox', major: '89' },
273
- device: {}
274
- }));
275
-
276
- const result = UserAgent.getData('Mozilla/5.0...');
277
-
256
+ const ua = 'Mozilla/5.0 (X11; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0';
257
+ const result = UserAgent.getData(ua);
278
258
  expect(result.os).toBe('Linux');
279
-
280
- delete global.UAParser;
281
- });
282
-
283
- test('should handle browser with version instead of major', () => {
284
- global.UAParser = jest.fn(() => ({
285
- os: { name: 'Windows', version: '10' },
286
- browser: { name: 'Safari', version: '14.1.2' },
287
- device: {}
288
- }));
289
-
290
- const result = UserAgent.getData('Mozilla/5.0...');
291
-
292
- expect(result.browser).toBe('Safari 14.1.2');
293
-
294
- delete global.UAParser;
295
- });
296
-
297
- test('should handle device with only type', () => {
298
- global.UAParser = jest.fn(() => ({
299
- os: { name: 'iOS', version: '14' },
300
- browser: { name: 'Safari', major: '14' },
301
- device: { type: 'mobile' }
302
- }));
303
-
304
- const result = UserAgent.getData('Mozilla/5.0...');
305
-
306
- expect(result.device).toBe('mobile');
307
-
308
- delete global.UAParser;
309
259
  });
310
260
 
311
- test('should return null for empty os', () => {
312
- global.UAParser = jest.fn(() => ({
313
- os: { name: '' },
314
- browser: { name: 'Chrome', major: '91' },
315
- device: {}
316
- }));
317
-
318
- const result = UserAgent.getData('Mozilla/5.0...');
319
-
320
- expect(result.os).toBeNull();
321
-
322
- delete global.UAParser;
261
+ test('should handle mobile device', () => {
262
+ const ua = 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1';
263
+ const result = UserAgent.getData(ua);
264
+ expect(result.device).toContain('mobile');
265
+ expect(result.device).toContain('Apple');
266
+ expect(result.device).toContain('iPhone');
323
267
  });
324
268
 
325
- test('should return null for empty browser', () => {
326
- global.UAParser = jest.fn(() => ({
327
- os: { name: 'Windows', version: '10' },
328
- browser: { name: '' },
329
- device: {}
330
- }));
331
-
332
- const result = UserAgent.getData('Mozilla/5.0...');
333
-
334
- expect(result.browser).toBeNull();
335
-
336
- delete global.UAParser;
337
- });
338
-
339
- test('should return null when all undefined', () => {
340
- global.UAParser = jest.fn(() => ({
341
- os: {},
342
- browser: {},
343
- device: {}
344
- }));
345
-
346
- const result = UserAgent.getData('Mozilla/5.0...');
347
-
348
- expect(result).toEqual({
349
- os: null,
350
- browser: null,
351
- device: null
352
- });
353
-
354
- delete global.UAParser;
269
+ test('should return all null for empty user agent', () => {
270
+ const result = UserAgent.getData('');
271
+ expect(result).toEqual({ os: null, browser: null, device: null });
355
272
  });
356
273
  });
357
274
 
package/visitor.js CHANGED
@@ -1,3 +1,5 @@
1
+ const { UAParser } = require('ua-parser-js');
2
+
1
3
  class Browser {
2
4
  static isOpera() {
3
5
  return (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
@@ -36,10 +38,6 @@ class UserAgent {
36
38
  }
37
39
 
38
40
  static getData(userAgent) {
39
- if (typeof UAParser == 'undefined') {
40
- return null;
41
- }
42
-
43
41
  const parsedData = UAParser(userAgent);
44
42
 
45
43
  let os = null;