@webority-technologies/mobile-core 0.0.1
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.md +15 -0
- package/lib/commonjs/api/publicClient.js +80 -0
- package/lib/commonjs/api/userClient.js +368 -0
- package/lib/commonjs/auth/authStore.js +155 -0
- package/lib/commonjs/auth/index.js +44 -0
- package/lib/commonjs/auth/jwt.js +88 -0
- package/lib/commonjs/config/index.js +65 -0
- package/lib/commonjs/formatters/currency.js +69 -0
- package/lib/commonjs/formatters/date.js +168 -0
- package/lib/commonjs/formatters/index.js +77 -0
- package/lib/commonjs/formatters/initials.js +32 -0
- package/lib/commonjs/formatters/number.js +88 -0
- package/lib/commonjs/formatters/phone.js +67 -0
- package/lib/commonjs/index.js +383 -0
- package/lib/commonjs/initSDK.js +45 -0
- package/lib/commonjs/initUserAuth.js +38 -0
- package/lib/commonjs/logger/index.js +137 -0
- package/lib/commonjs/network/index.js +25 -0
- package/lib/commonjs/network/networkStatus.js +98 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/permissions/index.js +200 -0
- package/lib/commonjs/storage/index.js +193 -0
- package/lib/commonjs/utils/imageCompression.js +75 -0
- package/lib/commonjs/utils/index.js +13 -0
- package/lib/commonjs/validators/index.js +193 -0
- package/lib/commonjs/versionCheck/index.js +395 -0
- package/lib/module/api/publicClient.js +76 -0
- package/lib/module/api/userClient.js +360 -0
- package/lib/module/auth/authStore.js +148 -0
- package/lib/module/auth/index.js +5 -0
- package/lib/module/auth/jwt.js +82 -0
- package/lib/module/config/index.js +57 -0
- package/lib/module/formatters/currency.js +64 -0
- package/lib/module/formatters/date.js +160 -0
- package/lib/module/formatters/index.js +8 -0
- package/lib/module/formatters/initials.js +27 -0
- package/lib/module/formatters/number.js +81 -0
- package/lib/module/formatters/phone.js +61 -0
- package/lib/module/index.js +30 -0
- package/lib/module/initSDK.js +40 -0
- package/lib/module/initUserAuth.js +34 -0
- package/lib/module/logger/index.js +133 -0
- package/lib/module/network/index.js +4 -0
- package/lib/module/network/networkStatus.js +91 -0
- package/lib/module/package.json +1 -0
- package/lib/module/permissions/index.js +197 -0
- package/lib/module/storage/index.js +189 -0
- package/lib/module/utils/imageCompression.js +69 -0
- package/lib/module/utils/index.js +4 -0
- package/lib/module/validators/index.js +171 -0
- package/lib/module/versionCheck/index.js +390 -0
- package/lib/typescript/commonjs/api/publicClient.d.ts +11 -0
- package/lib/typescript/commonjs/api/userClient.d.ts +49 -0
- package/lib/typescript/commonjs/auth/authStore.d.ts +43 -0
- package/lib/typescript/commonjs/auth/index.d.ts +5 -0
- package/lib/typescript/commonjs/auth/jwt.d.ts +31 -0
- package/lib/typescript/commonjs/config/index.d.ts +49 -0
- package/lib/typescript/commonjs/formatters/currency.d.ts +24 -0
- package/lib/typescript/commonjs/formatters/date.d.ts +22 -0
- package/lib/typescript/commonjs/formatters/index.d.ts +8 -0
- package/lib/typescript/commonjs/formatters/initials.d.ts +11 -0
- package/lib/typescript/commonjs/formatters/number.d.ts +15 -0
- package/lib/typescript/commonjs/formatters/phone.d.ts +13 -0
- package/lib/typescript/commonjs/index.d.ts +30 -0
- package/lib/typescript/commonjs/initSDK.d.ts +40 -0
- package/lib/typescript/commonjs/initUserAuth.d.ts +22 -0
- package/lib/typescript/commonjs/logger/index.d.ts +42 -0
- package/lib/typescript/commonjs/network/index.d.ts +3 -0
- package/lib/typescript/commonjs/network/networkStatus.d.ts +27 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/permissions/index.d.ts +20 -0
- package/lib/typescript/commonjs/storage/index.d.ts +42 -0
- package/lib/typescript/commonjs/utils/imageCompression.d.ts +31 -0
- package/lib/typescript/commonjs/utils/index.d.ts +3 -0
- package/lib/typescript/commonjs/validators/index.d.ts +46 -0
- package/lib/typescript/commonjs/versionCheck/index.d.ts +80 -0
- package/lib/typescript/module/api/publicClient.d.ts +11 -0
- package/lib/typescript/module/api/userClient.d.ts +49 -0
- package/lib/typescript/module/auth/authStore.d.ts +43 -0
- package/lib/typescript/module/auth/index.d.ts +5 -0
- package/lib/typescript/module/auth/jwt.d.ts +31 -0
- package/lib/typescript/module/config/index.d.ts +49 -0
- package/lib/typescript/module/formatters/currency.d.ts +24 -0
- package/lib/typescript/module/formatters/date.d.ts +22 -0
- package/lib/typescript/module/formatters/index.d.ts +8 -0
- package/lib/typescript/module/formatters/initials.d.ts +11 -0
- package/lib/typescript/module/formatters/number.d.ts +15 -0
- package/lib/typescript/module/formatters/phone.d.ts +13 -0
- package/lib/typescript/module/index.d.ts +30 -0
- package/lib/typescript/module/initSDK.d.ts +40 -0
- package/lib/typescript/module/initUserAuth.d.ts +22 -0
- package/lib/typescript/module/logger/index.d.ts +42 -0
- package/lib/typescript/module/network/index.d.ts +3 -0
- package/lib/typescript/module/network/networkStatus.d.ts +27 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/permissions/index.d.ts +20 -0
- package/lib/typescript/module/storage/index.d.ts +42 -0
- package/lib/typescript/module/utils/imageCompression.d.ts +31 -0
- package/lib/typescript/module/utils/index.d.ts +3 -0
- package/lib/typescript/module/validators/index.d.ts +46 -0
- package/lib/typescript/module/versionCheck/index.d.ts +80 -0
- package/package.json +112 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isJWTExpired = exports.getJWTExpiry = exports.decodeJWT = void 0;
|
|
7
|
+
var _index = require("../logger/index.js");
|
|
8
|
+
/**
|
|
9
|
+
* Standard claims plus arbitrary keys.
|
|
10
|
+
* `sub`, `exp`, `iat`, `nbf` follow RFC 7519 conventions.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const base64UrlToBase64 = input => {
|
|
14
|
+
const padded = input + '='.repeat((4 - input.length % 4) % 4);
|
|
15
|
+
return padded.replace(/-/g, '+').replace(/_/g, '/');
|
|
16
|
+
};
|
|
17
|
+
const decodeBase64 = input => {
|
|
18
|
+
// RN runtimes expose `atob` (Hermes 0.71+); fall back to a Buffer-based decode otherwise.
|
|
19
|
+
if (typeof atob === 'function') {
|
|
20
|
+
return atob(input);
|
|
21
|
+
}
|
|
22
|
+
const {
|
|
23
|
+
Buffer
|
|
24
|
+
} = require('buffer');
|
|
25
|
+
return Buffer.from(input, 'base64').toString('utf-8');
|
|
26
|
+
};
|
|
27
|
+
const utf8FromBinary = binary => {
|
|
28
|
+
// Convert percent-encoded UTF-8 sequence so multi-byte chars survive.
|
|
29
|
+
try {
|
|
30
|
+
return decodeURIComponent(binary.split('').map(c => '%' + c.charCodeAt(0).toString(16).padStart(2, '0')).join(''));
|
|
31
|
+
} catch {
|
|
32
|
+
return binary;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Decode a JWT's payload claims. Does **not** verify the signature.
|
|
38
|
+
*
|
|
39
|
+
* @returns claims object on success, `null` if the token is malformed.
|
|
40
|
+
*/
|
|
41
|
+
const decodeJWT = token => {
|
|
42
|
+
if (!token || typeof token !== 'string') {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const parts = token.split('.');
|
|
46
|
+
if (parts.length !== 3) {
|
|
47
|
+
_index.Logger.warn('[jwt] decodeJWT: token is not a valid JWT (expected 3 segments)');
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const payload = parts[1];
|
|
52
|
+
const json = utf8FromBinary(decodeBase64(base64UrlToBase64(payload)));
|
|
53
|
+
return JSON.parse(json);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
_index.Logger.warn('[jwt] decodeJWT failed to parse payload', error);
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Returns true when the token is expired (or unparseable / missing `exp`).
|
|
62
|
+
*
|
|
63
|
+
* @param token JWT string
|
|
64
|
+
* @param leewaySeconds amount of clock-skew tolerance to apply (default 30s)
|
|
65
|
+
*/
|
|
66
|
+
exports.decodeJWT = decodeJWT;
|
|
67
|
+
const isJWTExpired = (token, leewaySeconds = 30) => {
|
|
68
|
+
const claims = decodeJWT(token);
|
|
69
|
+
if (!claims || typeof claims.exp !== 'number') {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
const nowSeconds = Math.floor(Date.now() / 1000);
|
|
73
|
+
return claims.exp <= nowSeconds + leewaySeconds;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Returns the token's expiry as a Date, or `null` when no `exp` claim exists.
|
|
78
|
+
*/
|
|
79
|
+
exports.isJWTExpired = isJWTExpired;
|
|
80
|
+
const getJWTExpiry = token => {
|
|
81
|
+
const claims = decodeJWT(token);
|
|
82
|
+
if (!claims || typeof claims.exp !== 'number') {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
return new Date(claims.exp * 1000);
|
|
86
|
+
};
|
|
87
|
+
exports.getJWTExpiry = getJWTExpiry;
|
|
88
|
+
//# sourceMappingURL=jwt.js.map
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getConfig = void 0;
|
|
7
|
+
exports.getConfigValue = getConfigValue;
|
|
8
|
+
exports.setConfig = exports.resetConfig = void 0;
|
|
9
|
+
/**
|
|
10
|
+
* Configuration management for Webority packages
|
|
11
|
+
* Provides a flexible way to inject configuration without hard dependencies
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const DEFAULT_CONFIG = {
|
|
15
|
+
baseUrl: null,
|
|
16
|
+
loggingEnabled: true,
|
|
17
|
+
logLevel: 'info',
|
|
18
|
+
environment: 'Development',
|
|
19
|
+
country: 'in',
|
|
20
|
+
appId: null,
|
|
21
|
+
appVersion: null
|
|
22
|
+
};
|
|
23
|
+
let globalConfig = {
|
|
24
|
+
...DEFAULT_CONFIG
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Set global configuration for all Webority packages
|
|
29
|
+
*/
|
|
30
|
+
const setConfig = config => {
|
|
31
|
+
globalConfig = {
|
|
32
|
+
...globalConfig,
|
|
33
|
+
...config
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Get current configuration
|
|
39
|
+
*/
|
|
40
|
+
exports.setConfig = setConfig;
|
|
41
|
+
const getConfig = () => globalConfig;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Get a specific config value with optional fallback.
|
|
45
|
+
* If the stored value is `null`, the fallback is returned (when provided).
|
|
46
|
+
*/
|
|
47
|
+
exports.getConfig = getConfig;
|
|
48
|
+
function getConfigValue(key, fallback) {
|
|
49
|
+
const value = globalConfig[key];
|
|
50
|
+
if (value !== null) {
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
return fallback;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Reset configuration to defaults
|
|
58
|
+
*/
|
|
59
|
+
const resetConfig = () => {
|
|
60
|
+
globalConfig = {
|
|
61
|
+
...DEFAULT_CONFIG
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
exports.resetConfig = resetConfig;
|
|
65
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.formatCurrency = void 0;
|
|
7
|
+
const hasIntlNumber = () => typeof Intl !== 'undefined' && typeof Intl.NumberFormat === 'function';
|
|
8
|
+
const indianGroupingFallback = (n, fractionDigits) => {
|
|
9
|
+
// Indian numbering: 1,23,45,678.90 (last 3 digits, then groups of 2).
|
|
10
|
+
const sign = n < 0 ? '-' : '';
|
|
11
|
+
const abs = Math.abs(n);
|
|
12
|
+
const fixed = abs.toFixed(fractionDigits);
|
|
13
|
+
const [intPart, decPart] = fixed.split('.');
|
|
14
|
+
const last3 = intPart.length > 3 ? intPart.slice(-3) : intPart;
|
|
15
|
+
const rest = intPart.length > 3 ? intPart.slice(0, -3) : '';
|
|
16
|
+
const grouped = rest ? rest.replace(/\B(?=(\d{2})+(?!\d))/g, ',') + ',' + last3 : last3;
|
|
17
|
+
return sign + grouped + (decPart ? `.${decPart}` : '');
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Format an amount as currency. Defaults to **INR** with Indian numbering (`en-IN`),
|
|
22
|
+
* which matches the standard convention across Webority projects.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* formatCurrency(150000) // ₹1,50,000
|
|
26
|
+
* formatCurrency(1234.5) // ₹1,234.50
|
|
27
|
+
* formatCurrency(99, { currency: 'USD', locale: 'en-US' }) // $99.00
|
|
28
|
+
* formatCurrency(150000, { stripSymbol: true }) // 1,50,000
|
|
29
|
+
*/
|
|
30
|
+
const formatCurrency = (amount, options = {}) => {
|
|
31
|
+
if (amount == null || Number.isNaN(amount)) {
|
|
32
|
+
return '';
|
|
33
|
+
}
|
|
34
|
+
const {
|
|
35
|
+
currency = 'INR',
|
|
36
|
+
locale = 'en-IN',
|
|
37
|
+
minimumFractionDigits,
|
|
38
|
+
maximumFractionDigits = 2,
|
|
39
|
+
stripSymbol = false
|
|
40
|
+
} = options;
|
|
41
|
+
const minFrac = minimumFractionDigits ?? (Number.isInteger(amount) ? 0 : 2);
|
|
42
|
+
if (hasIntlNumber()) {
|
|
43
|
+
try {
|
|
44
|
+
const formatted = new Intl.NumberFormat(locale, {
|
|
45
|
+
style: 'currency',
|
|
46
|
+
currency,
|
|
47
|
+
minimumFractionDigits: minFrac,
|
|
48
|
+
maximumFractionDigits
|
|
49
|
+
}).format(amount);
|
|
50
|
+
if (!stripSymbol) {
|
|
51
|
+
return formatted;
|
|
52
|
+
}
|
|
53
|
+
// Strip currency code/symbol while keeping digits, separators and sign.
|
|
54
|
+
return formatted.replace(/[^\d,.\s\-+]/g, '').trim();
|
|
55
|
+
} catch {
|
|
56
|
+
/* fall through to fallback */
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const numeric = indianGroupingFallback(amount, minFrac);
|
|
60
|
+
if (stripSymbol) {
|
|
61
|
+
return numeric;
|
|
62
|
+
}
|
|
63
|
+
if (currency === 'INR') {
|
|
64
|
+
return `₹${numeric}`;
|
|
65
|
+
}
|
|
66
|
+
return `${currency} ${numeric}`;
|
|
67
|
+
};
|
|
68
|
+
exports.formatCurrency = formatCurrency;
|
|
69
|
+
//# sourceMappingURL=currency.js.map
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.formatTime = exports.formatRelativeTime = exports.formatDateTime = exports.formatDate = void 0;
|
|
7
|
+
const toDate = value => {
|
|
8
|
+
if (value instanceof Date) {
|
|
9
|
+
return Number.isNaN(value.getTime()) ? null : value;
|
|
10
|
+
}
|
|
11
|
+
const d = new Date(value);
|
|
12
|
+
return Number.isNaN(d.getTime()) ? null : d;
|
|
13
|
+
};
|
|
14
|
+
const hasIntl = () => typeof Intl !== 'undefined' && typeof Intl.DateTimeFormat === 'function';
|
|
15
|
+
const PAD = n => n < 10 ? `0${n}` : `${n}`;
|
|
16
|
+
const fallbackDate = (d, style) => {
|
|
17
|
+
const day = PAD(d.getDate());
|
|
18
|
+
const monthShort = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][d.getMonth()];
|
|
19
|
+
const monthLong = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'][d.getMonth()];
|
|
20
|
+
const year = d.getFullYear();
|
|
21
|
+
const weekdayLong = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][d.getDay()];
|
|
22
|
+
switch (style) {
|
|
23
|
+
case 'short':
|
|
24
|
+
return `${day}/${PAD(d.getMonth() + 1)}/${year}`;
|
|
25
|
+
case 'long':
|
|
26
|
+
return `${day} ${monthLong} ${year}`;
|
|
27
|
+
case 'full':
|
|
28
|
+
return `${weekdayLong}, ${day} ${monthLong} ${year}`;
|
|
29
|
+
case 'medium':
|
|
30
|
+
default:
|
|
31
|
+
return `${day} ${monthShort} ${year}`;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const fallbackTime = (d, style) => {
|
|
35
|
+
const hh = PAD(d.getHours());
|
|
36
|
+
const mm = PAD(d.getMinutes());
|
|
37
|
+
if (style === 'short') {
|
|
38
|
+
return `${hh}:${mm}`;
|
|
39
|
+
}
|
|
40
|
+
const ss = PAD(d.getSeconds());
|
|
41
|
+
return `${hh}:${mm}:${ss}`;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Locale-aware date formatter. Defaults to `'medium'` style and `'en-IN'` locale,
|
|
46
|
+
* matching the Indian-locale convention used across Webority apps.
|
|
47
|
+
*/
|
|
48
|
+
const formatDate = (value, style = 'medium', locale = 'en-IN') => {
|
|
49
|
+
const d = toDate(value);
|
|
50
|
+
if (!d) {
|
|
51
|
+
return '';
|
|
52
|
+
}
|
|
53
|
+
if (hasIntl()) {
|
|
54
|
+
try {
|
|
55
|
+
return new Intl.DateTimeFormat(locale, {
|
|
56
|
+
dateStyle: style
|
|
57
|
+
}).format(d);
|
|
58
|
+
} catch {
|
|
59
|
+
/* fall through to fallback */
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return fallbackDate(d, style);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Locale-aware time formatter (24-hour fallback when Intl is unavailable).
|
|
67
|
+
*/
|
|
68
|
+
exports.formatDate = formatDate;
|
|
69
|
+
const formatTime = (value, style = 'short', locale = 'en-IN') => {
|
|
70
|
+
const d = toDate(value);
|
|
71
|
+
if (!d) {
|
|
72
|
+
return '';
|
|
73
|
+
}
|
|
74
|
+
if (hasIntl()) {
|
|
75
|
+
try {
|
|
76
|
+
return new Intl.DateTimeFormat(locale, {
|
|
77
|
+
timeStyle: style
|
|
78
|
+
}).format(d);
|
|
79
|
+
} catch {
|
|
80
|
+
/* fall through */
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return fallbackTime(d, style);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Combined date + time formatter.
|
|
88
|
+
*/
|
|
89
|
+
exports.formatTime = formatTime;
|
|
90
|
+
const formatDateTime = (value, dateStyle = 'medium', timeStyle = 'short', locale = 'en-IN') => {
|
|
91
|
+
const d = toDate(value);
|
|
92
|
+
if (!d) {
|
|
93
|
+
return '';
|
|
94
|
+
}
|
|
95
|
+
if (hasIntl()) {
|
|
96
|
+
try {
|
|
97
|
+
return new Intl.DateTimeFormat(locale, {
|
|
98
|
+
dateStyle,
|
|
99
|
+
timeStyle
|
|
100
|
+
}).format(d);
|
|
101
|
+
} catch {
|
|
102
|
+
/* fall through */
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return `${fallbackDate(d, dateStyle)}, ${fallbackTime(d, timeStyle)}`;
|
|
106
|
+
};
|
|
107
|
+
exports.formatDateTime = formatDateTime;
|
|
108
|
+
const SECOND = 1000;
|
|
109
|
+
const MINUTE = 60 * SECOND;
|
|
110
|
+
const HOUR = 60 * MINUTE;
|
|
111
|
+
const DAY = 24 * HOUR;
|
|
112
|
+
const WEEK = 7 * DAY;
|
|
113
|
+
const MONTH = 30 * DAY;
|
|
114
|
+
const YEAR = 365 * DAY;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Returns a humanized relative-time string (e.g. "5 minutes ago", "in 3 days").
|
|
118
|
+
* Uses `Intl.RelativeTimeFormat` when available; otherwise a sensible English fallback.
|
|
119
|
+
*/
|
|
120
|
+
const formatRelativeTime = (value, base = new Date(), locale = 'en-IN') => {
|
|
121
|
+
const target = toDate(value);
|
|
122
|
+
const now = toDate(base);
|
|
123
|
+
if (!target || !now) {
|
|
124
|
+
return '';
|
|
125
|
+
}
|
|
126
|
+
const diffMs = target.getTime() - now.getTime();
|
|
127
|
+
const abs = Math.abs(diffMs);
|
|
128
|
+
let unit;
|
|
129
|
+
let amount;
|
|
130
|
+
if (abs < MINUTE) {
|
|
131
|
+
unit = 'second';
|
|
132
|
+
amount = Math.round(diffMs / SECOND);
|
|
133
|
+
} else if (abs < HOUR) {
|
|
134
|
+
unit = 'minute';
|
|
135
|
+
amount = Math.round(diffMs / MINUTE);
|
|
136
|
+
} else if (abs < DAY) {
|
|
137
|
+
unit = 'hour';
|
|
138
|
+
amount = Math.round(diffMs / HOUR);
|
|
139
|
+
} else if (abs < WEEK) {
|
|
140
|
+
unit = 'day';
|
|
141
|
+
amount = Math.round(diffMs / DAY);
|
|
142
|
+
} else if (abs < MONTH) {
|
|
143
|
+
unit = 'week';
|
|
144
|
+
amount = Math.round(diffMs / WEEK);
|
|
145
|
+
} else if (abs < YEAR) {
|
|
146
|
+
unit = 'month';
|
|
147
|
+
amount = Math.round(diffMs / MONTH);
|
|
148
|
+
} else {
|
|
149
|
+
unit = 'year';
|
|
150
|
+
amount = Math.round(diffMs / YEAR);
|
|
151
|
+
}
|
|
152
|
+
const Rtf = Intl.RelativeTimeFormat;
|
|
153
|
+
if (typeof Rtf === 'function') {
|
|
154
|
+
try {
|
|
155
|
+
return new Rtf(locale, {
|
|
156
|
+
numeric: 'auto'
|
|
157
|
+
}).format(amount, unit);
|
|
158
|
+
} catch {
|
|
159
|
+
/* fall through */
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const past = amount < 0;
|
|
163
|
+
const n = Math.abs(amount);
|
|
164
|
+
const u = n === 1 ? unit : `${unit}s`;
|
|
165
|
+
return past ? `${n} ${u} ago` : `in ${n} ${u}`;
|
|
166
|
+
};
|
|
167
|
+
exports.formatRelativeTime = formatRelativeTime;
|
|
168
|
+
//# sourceMappingURL=date.js.map
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "formatCompactNumber", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _number.formatCompactNumber;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "formatCurrency", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _currency.formatCurrency;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "formatDate", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _date.formatDate;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "formatDateTime", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _date.formatDateTime;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(exports, "formatNumber", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () {
|
|
33
|
+
return _number.formatNumber;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(exports, "formatPercent", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function () {
|
|
39
|
+
return _number.formatPercent;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(exports, "formatPhone", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function () {
|
|
45
|
+
return _phone.formatPhone;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperty(exports, "formatRelativeTime", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function () {
|
|
51
|
+
return _date.formatRelativeTime;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
Object.defineProperty(exports, "formatTime", {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function () {
|
|
57
|
+
return _date.formatTime;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
Object.defineProperty(exports, "getInitials", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
get: function () {
|
|
63
|
+
return _initials.getInitials;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
Object.defineProperty(exports, "normalizePhone", {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
get: function () {
|
|
69
|
+
return _phone.normalizePhone;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
var _currency = require("./currency.js");
|
|
73
|
+
var _date = require("./date.js");
|
|
74
|
+
var _initials = require("./initials.js");
|
|
75
|
+
var _number = require("./number.js");
|
|
76
|
+
var _phone = require("./phone.js");
|
|
77
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getInitials = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Returns up to `maxChars` uppercase initials from a name.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* getInitials('Navneet Singh') // 'NS'
|
|
12
|
+
* getInitials('mary anne lee', 3) // 'MAL'
|
|
13
|
+
* getInitials('navneet') // 'NA'
|
|
14
|
+
* getInitials(' ') // ''
|
|
15
|
+
*/
|
|
16
|
+
const getInitials = (name, maxChars = 2) => {
|
|
17
|
+
if (!name) {
|
|
18
|
+
return '';
|
|
19
|
+
}
|
|
20
|
+
const trimmed = name.trim();
|
|
21
|
+
if (!trimmed) {
|
|
22
|
+
return '';
|
|
23
|
+
}
|
|
24
|
+
const parts = trimmed.split(/\s+/);
|
|
25
|
+
if (parts.length === 1) {
|
|
26
|
+
const single = parts[0] ?? '';
|
|
27
|
+
return single.slice(0, maxChars).toUpperCase();
|
|
28
|
+
}
|
|
29
|
+
return parts.slice(0, maxChars).map(p => (p[0] ?? '').toUpperCase()).join('');
|
|
30
|
+
};
|
|
31
|
+
exports.getInitials = getInitials;
|
|
32
|
+
//# sourceMappingURL=initials.js.map
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.formatPercent = exports.formatNumber = exports.formatCompactNumber = void 0;
|
|
7
|
+
const hasIntlNumber = () => typeof Intl !== 'undefined' && typeof Intl.NumberFormat === 'function';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Locale-aware number formatter. Defaults to `'en-IN'` (Indian grouping).
|
|
11
|
+
*/
|
|
12
|
+
const formatNumber = (value, fractionDigits, locale = 'en-IN') => {
|
|
13
|
+
if (value == null || Number.isNaN(value)) {
|
|
14
|
+
return '';
|
|
15
|
+
}
|
|
16
|
+
if (hasIntlNumber()) {
|
|
17
|
+
try {
|
|
18
|
+
const opts = {};
|
|
19
|
+
if (fractionDigits != null) {
|
|
20
|
+
opts.minimumFractionDigits = fractionDigits;
|
|
21
|
+
opts.maximumFractionDigits = fractionDigits;
|
|
22
|
+
}
|
|
23
|
+
return new Intl.NumberFormat(locale, opts).format(value);
|
|
24
|
+
} catch {
|
|
25
|
+
/* fall through */
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return fractionDigits != null ? value.toFixed(fractionDigits) : String(value);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Format a 0–1 ratio (or 0–100 percent) as a percent string.
|
|
33
|
+
* Pass `asRatio: false` if your input is already on the 0–100 scale.
|
|
34
|
+
*/
|
|
35
|
+
exports.formatNumber = formatNumber;
|
|
36
|
+
const formatPercent = (value, fractionDigits = 0, asRatio = true, locale = 'en-IN') => {
|
|
37
|
+
if (value == null || Number.isNaN(value)) {
|
|
38
|
+
return '';
|
|
39
|
+
}
|
|
40
|
+
const ratio = asRatio ? value : value / 100;
|
|
41
|
+
if (hasIntlNumber()) {
|
|
42
|
+
try {
|
|
43
|
+
return new Intl.NumberFormat(locale, {
|
|
44
|
+
style: 'percent',
|
|
45
|
+
minimumFractionDigits: fractionDigits,
|
|
46
|
+
maximumFractionDigits: fractionDigits
|
|
47
|
+
}).format(ratio);
|
|
48
|
+
} catch {
|
|
49
|
+
/* fall through */
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return `${(ratio * 100).toFixed(fractionDigits)}%`;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Format a number compactly (1.2K, 3.4M, 1.5L, 2.3Cr).
|
|
57
|
+
* Defaults to Indian compact notation via `'en-IN'` locale (lakh / crore).
|
|
58
|
+
*/
|
|
59
|
+
exports.formatPercent = formatPercent;
|
|
60
|
+
const formatCompactNumber = (value, locale = 'en-IN') => {
|
|
61
|
+
if (value == null || Number.isNaN(value)) {
|
|
62
|
+
return '';
|
|
63
|
+
}
|
|
64
|
+
if (hasIntlNumber()) {
|
|
65
|
+
try {
|
|
66
|
+
return new Intl.NumberFormat(locale, {
|
|
67
|
+
notation: 'compact',
|
|
68
|
+
maximumFractionDigits: 1
|
|
69
|
+
}).format(value);
|
|
70
|
+
} catch {
|
|
71
|
+
/* fall through */
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const abs = Math.abs(value);
|
|
75
|
+
const sign = value < 0 ? '-' : '';
|
|
76
|
+
if (abs >= 1e7) {
|
|
77
|
+
return `${sign}${(abs / 1e7).toFixed(1)}Cr`;
|
|
78
|
+
}
|
|
79
|
+
if (abs >= 1e5) {
|
|
80
|
+
return `${sign}${(abs / 1e5).toFixed(1)}L`;
|
|
81
|
+
}
|
|
82
|
+
if (abs >= 1e3) {
|
|
83
|
+
return `${sign}${(abs / 1e3).toFixed(1)}K`;
|
|
84
|
+
}
|
|
85
|
+
return `${value}`;
|
|
86
|
+
};
|
|
87
|
+
exports.formatCompactNumber = formatCompactNumber;
|
|
88
|
+
//# sourceMappingURL=number.js.map
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.normalizePhone = exports.formatPhone = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Strip everything except digits and a leading `+` (preserved if present).
|
|
9
|
+
*/
|
|
10
|
+
const normalizePhone = input => {
|
|
11
|
+
if (!input) {
|
|
12
|
+
return '';
|
|
13
|
+
}
|
|
14
|
+
const trimmed = input.trim();
|
|
15
|
+
const hasPlus = trimmed.startsWith('+');
|
|
16
|
+
const digits = trimmed.replace(/\D/g, '');
|
|
17
|
+
return hasPlus ? `+${digits}` : digits;
|
|
18
|
+
};
|
|
19
|
+
exports.normalizePhone = normalizePhone;
|
|
20
|
+
const groupIndianMobile = digits => {
|
|
21
|
+
// Indian mobile is 10 digits: format as `XXXXX XXXXX`.
|
|
22
|
+
if (digits.length !== 10) {
|
|
23
|
+
return digits;
|
|
24
|
+
}
|
|
25
|
+
return `${digits.slice(0, 5)} ${digits.slice(5)}`;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Format a phone number for human display.
|
|
30
|
+
*
|
|
31
|
+
* - Indian mobile (10 digits) → `XXXXX XXXXX`
|
|
32
|
+
* - With `+91` country code → `+91 XXXXX XXXXX`
|
|
33
|
+
* - Other inputs are returned as `+CC NNNN NNNN…` best-effort grouping.
|
|
34
|
+
*/
|
|
35
|
+
const formatPhone = (input, defaultCountryCode = '+91') => {
|
|
36
|
+
if (!input) {
|
|
37
|
+
return '';
|
|
38
|
+
}
|
|
39
|
+
const normalized = normalizePhone(input);
|
|
40
|
+
if (!normalized) {
|
|
41
|
+
return '';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Already starts with +
|
|
45
|
+
if (normalized.startsWith('+')) {
|
|
46
|
+
const rest = normalized.slice(1);
|
|
47
|
+
// Indian
|
|
48
|
+
if (rest.startsWith('91') && rest.length === 12) {
|
|
49
|
+
return `+91 ${groupIndianMobile(rest.slice(2))}`;
|
|
50
|
+
}
|
|
51
|
+
// Generic — split country code (first 1–3 digits) and group the rest in 4s.
|
|
52
|
+
const ccLen = rest.length > 11 ? 3 : rest.length > 10 ? 2 : 1;
|
|
53
|
+
const cc = rest.slice(0, ccLen);
|
|
54
|
+
const number = rest.slice(ccLen);
|
|
55
|
+
const grouped = number.replace(/(.{4})(?=.)/g, '$1 ').trim();
|
|
56
|
+
return `+${cc} ${grouped}`.trim();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// No country code; assume default if length matches Indian mobile.
|
|
60
|
+
if (normalized.length === 10) {
|
|
61
|
+
return `${defaultCountryCode} ${groupIndianMobile(normalized)}`;
|
|
62
|
+
}
|
|
63
|
+
// Otherwise just return groups of 4.
|
|
64
|
+
return normalized.replace(/(.{4})(?=.)/g, '$1 ').trim();
|
|
65
|
+
};
|
|
66
|
+
exports.formatPhone = formatPhone;
|
|
67
|
+
//# sourceMappingURL=phone.js.map
|