@dakkiin/eida 0.1.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/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/useCurrency.d.ts +98 -0
- package/dist/useCurrency.d.ts.map +1 -0
- package/dist/useCurrency.js +119 -0
- package/dist/useFormatDate.d.ts +7 -0
- package/dist/useFormatDate.d.ts.map +1 -0
- package/dist/useFormatDate.js +65 -0
- package/dist/useNumbersToWords.d.ts +4 -0
- package/dist/useNumbersToWords.d.ts.map +1 -0
- package/dist/useNumbersToWords.js +124 -0
- package/package.json +40 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
|
|
3
|
+
* @packageDocumentation useCurrency
|
|
4
|
+
* @module useCurrency
|
|
5
|
+
* @description Currency conversion utilities
|
|
6
|
+
*/
|
|
7
|
+
export type CurrencyCode = string;
|
|
8
|
+
/** ISO currency code or any consistent string identifier (e.g. "IQD", "USD"). */
|
|
9
|
+
export interface ConvertCurrencyDirectOptions {
|
|
10
|
+
amount: number;
|
|
11
|
+
/** Currency the `amount` is expressed in */
|
|
12
|
+
from: CurrencyCode;
|
|
13
|
+
/** Desired output currency */
|
|
14
|
+
to: CurrencyCode;
|
|
15
|
+
/**
|
|
16
|
+
* **Units of `to` per one unit of `from`** — multiplied by `amount`.
|
|
17
|
+
*
|
|
18
|
+
* @example 1 USD = 1480 IQD → converting USD→IQD: `directRate: 1480`.
|
|
19
|
+
*/
|
|
20
|
+
directRate: number;
|
|
21
|
+
}
|
|
22
|
+
export interface ConvertCurrencyViaBaseOptions {
|
|
23
|
+
amount: number;
|
|
24
|
+
from: CurrencyCode;
|
|
25
|
+
to: CurrencyCode;
|
|
26
|
+
/** Reference currency the `quotes` map is expressed against */
|
|
27
|
+
baseCurrency: CurrencyCode;
|
|
28
|
+
/**
|
|
29
|
+
* For each currency `c` (≠ base when converting), **`quotes[c]`** = how many units
|
|
30
|
+
* of **`c`** equal **one unit of `baseCurrency`**.
|
|
31
|
+
*
|
|
32
|
+
* @example Base USD, 1 USD = 1480 IQD → `quotes.IQD === 1480`.
|
|
33
|
+
*/
|
|
34
|
+
quotes: Partial<Record<CurrencyCode, number>>;
|
|
35
|
+
}
|
|
36
|
+
export type ConvertCurrencyOptions = ConvertCurrencyDirectOptions | ConvertCurrencyViaBaseOptions;
|
|
37
|
+
export declare const useCurrency: () => {
|
|
38
|
+
convertCurrency: typeof convertCurrency;
|
|
39
|
+
convertCurrencyWithDirectRate: typeof convertCurrencyWithDirectRate;
|
|
40
|
+
convertCurrencyViaBase: typeof convertCurrencyViaBase;
|
|
41
|
+
roundMoney: typeof roundMoney;
|
|
42
|
+
};
|
|
43
|
+
/** Case-insensitive (trimmed) comparison of currency codes */
|
|
44
|
+
/**
|
|
45
|
+
*
|
|
46
|
+
* @param a 'usd'
|
|
47
|
+
* @param b 'USD'
|
|
48
|
+
* @returns true
|
|
49
|
+
*/
|
|
50
|
+
export declare function sameCurrency(a: CurrencyCode, b: CurrencyCode): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Convert using one cross-rate: **`amount * directRate`** when `from` ≠ `to`.
|
|
53
|
+
*
|
|
54
|
+
* **`directRate` = units of `to` per 1 unit of `from`**.
|
|
55
|
+
*/
|
|
56
|
+
export declare function convertCurrencyWithDirectRate(amount: number, from: CurrencyCode, to: CurrencyCode, directRate: number): number;
|
|
57
|
+
/**
|
|
58
|
+
* Convert using quotes vs a base currency.
|
|
59
|
+
*
|
|
60
|
+
* **`quotes[c]`** = units of **`c`** per **1 × `baseCurrency`**.
|
|
61
|
+
* @example
|
|
62
|
+
* 100 USD → IQD with base USD:
|
|
63
|
+
* convertCurrencyViaBase(100, 'USD', 'IQD', 'USD', { IQD: 1480 })
|
|
64
|
+
* inBase = 100, out = 100 * 1480
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* 1480 IQD → USD
|
|
68
|
+
* convertCurrencyViaBase(1480, 'IQD', 'USD', 'USD', { IQD: 1480 })
|
|
69
|
+
* inBase = 1480 / 1480 = 1
|
|
70
|
+
*/
|
|
71
|
+
export declare function convertCurrencyViaBase(amount: number, from: CurrencyCode, to: CurrencyCode, baseCurrency: CurrencyCode, quotes: Partial<Record<CurrencyCode, number>>): number;
|
|
72
|
+
/**
|
|
73
|
+
* **Usage from USD to IQD.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* convertCurrency({
|
|
77
|
+
* amount: 100,
|
|
78
|
+
* from: 'USD',
|
|
79
|
+
* to: 'IQD',
|
|
80
|
+
* directRate: 1480,
|
|
81
|
+
* }) => 148000
|
|
82
|
+
*/
|
|
83
|
+
/**
|
|
84
|
+
* **1 USD = 1480 IQD → 1 IQD = 1/1480 USD
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* convertCurrency({
|
|
88
|
+
* amount: 100,
|
|
89
|
+
* from: 'USD',
|
|
90
|
+
* to: 'IQD',
|
|
91
|
+
* directRate: 1 / 1480,
|
|
92
|
+
* }) => 1
|
|
93
|
+
*/
|
|
94
|
+
/** Either **`directRate`** or **`baseCurrency` + **`quotes`** (not both shapes required on one union property set). */
|
|
95
|
+
export declare function convertCurrency(options: ConvertCurrencyOptions): number;
|
|
96
|
+
/** Round after conversion (fraction digits ≥ 0). */
|
|
97
|
+
export declare function roundMoney(value: number, fractionDigits?: number): number;
|
|
98
|
+
//# sourceMappingURL=useCurrency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCurrency.d.ts","sourceRoot":"","sources":["../src/useCurrency.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAA;AAEjC,iFAAiF;AAEjF,MAAM,WAAW,4BAA4B;IACzC,MAAM,EAAE,MAAM,CAAA;IACd,4CAA4C;IAC5C,IAAI,EAAE,YAAY,CAAA;IAClB,8BAA8B;IAC9B,EAAE,EAAE,YAAY,CAAA;IAChB;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,6BAA6B;IAC1C,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,YAAY,CAAA;IAClB,EAAE,EAAE,YAAY,CAAA;IAChB,+DAA+D;IAC/D,YAAY,EAAE,YAAY,CAAA;IAC1B;;;;;OAKG;IACH,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAA;CAChD;AAED,MAAM,MAAM,sBAAsB,GAAG,4BAA4B,GAAG,6BAA6B,CAAA;AAEjG,eAAO,MAAM,WAAW;;;;;CAOvB,CAAA;AAWD,8DAA8D;AAC9D;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,GAAG,OAAO,CAEtE;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CACzC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,YAAY,EAClB,EAAE,EAAE,YAAY,EAChB,UAAU,EAAE,MAAM,GACnB,MAAM,CAUR;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAClC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,YAAY,EAClB,EAAE,EAAE,YAAY,EAChB,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,GAC9C,MAAM,CA8BR;AAED;;;;;;;;;;OAUO;AAGP;;;;;;;;;;OAUO;AAEP,uHAAuH;AACvH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM,CAYvE;AAED,oDAAoD;AACpD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,SAAI,GAAG,MAAM,CAMpE"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
|
|
3
|
+
* @packageDocumentation useCurrency
|
|
4
|
+
* @module useCurrency
|
|
5
|
+
* @description Currency conversion utilities
|
|
6
|
+
*/
|
|
7
|
+
export const useCurrency = () => {
|
|
8
|
+
return {
|
|
9
|
+
convertCurrency,
|
|
10
|
+
convertCurrencyWithDirectRate,
|
|
11
|
+
convertCurrencyViaBase,
|
|
12
|
+
roundMoney,
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
function assertPositiveMultiplier(name, value) {
|
|
16
|
+
if (!Number.isFinite(value) || value <= 0)
|
|
17
|
+
throw new RangeError(`${name} must be a finite number greater than zero`);
|
|
18
|
+
}
|
|
19
|
+
function normalizeCode(code) {
|
|
20
|
+
return String(code).trim().toUpperCase();
|
|
21
|
+
}
|
|
22
|
+
/** Case-insensitive (trimmed) comparison of currency codes */
|
|
23
|
+
/**
|
|
24
|
+
*
|
|
25
|
+
* @param a 'usd'
|
|
26
|
+
* @param b 'USD'
|
|
27
|
+
* @returns true
|
|
28
|
+
*/
|
|
29
|
+
export function sameCurrency(a, b) {
|
|
30
|
+
return normalizeCode(a) === normalizeCode(b);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Convert using one cross-rate: **`amount * directRate`** when `from` ≠ `to`.
|
|
34
|
+
*
|
|
35
|
+
* **`directRate` = units of `to` per 1 unit of `from`**.
|
|
36
|
+
*/
|
|
37
|
+
export function convertCurrencyWithDirectRate(amount, from, to, directRate) {
|
|
38
|
+
if (!Number.isFinite(amount))
|
|
39
|
+
return Number.NaN;
|
|
40
|
+
if (sameCurrency(from, to))
|
|
41
|
+
return amount;
|
|
42
|
+
assertPositiveMultiplier('directRate', directRate);
|
|
43
|
+
return amount * directRate;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Convert using quotes vs a base currency.
|
|
47
|
+
*
|
|
48
|
+
* **`quotes[c]`** = units of **`c`** per **1 × `baseCurrency`**.
|
|
49
|
+
* @example
|
|
50
|
+
* 100 USD → IQD with base USD:
|
|
51
|
+
* convertCurrencyViaBase(100, 'USD', 'IQD', 'USD', { IQD: 1480 })
|
|
52
|
+
* inBase = 100, out = 100 * 1480
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* 1480 IQD → USD
|
|
56
|
+
* convertCurrencyViaBase(1480, 'IQD', 'USD', 'USD', { IQD: 1480 })
|
|
57
|
+
* inBase = 1480 / 1480 = 1
|
|
58
|
+
*/
|
|
59
|
+
export function convertCurrencyViaBase(amount, from, to, baseCurrency, quotes) {
|
|
60
|
+
if (!Number.isFinite(amount))
|
|
61
|
+
return Number.NaN;
|
|
62
|
+
const fromN = normalizeCode(from);
|
|
63
|
+
const toN = normalizeCode(to);
|
|
64
|
+
const baseN = normalizeCode(baseCurrency);
|
|
65
|
+
if (fromN === toN)
|
|
66
|
+
return amount;
|
|
67
|
+
const quoteOf = (code) => {
|
|
68
|
+
const v = quotes[normalizeCode(code)] ?? quotes[code];
|
|
69
|
+
if (v === undefined || v === null || !Number.isFinite(v) || v <= 0)
|
|
70
|
+
throw new RangeError(`Missing or invalid quote for "${code}" (units per 1 ${baseCurrency})`);
|
|
71
|
+
return v;
|
|
72
|
+
};
|
|
73
|
+
let inBase;
|
|
74
|
+
if (fromN === baseN)
|
|
75
|
+
inBase = amount;
|
|
76
|
+
else
|
|
77
|
+
inBase = amount / quoteOf(from);
|
|
78
|
+
if (toN === baseN)
|
|
79
|
+
return inBase;
|
|
80
|
+
return inBase * quoteOf(to);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* **Usage from USD to IQD.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* convertCurrency({
|
|
87
|
+
* amount: 100,
|
|
88
|
+
* from: 'USD',
|
|
89
|
+
* to: 'IQD',
|
|
90
|
+
* directRate: 1480,
|
|
91
|
+
* }) => 148000
|
|
92
|
+
*/
|
|
93
|
+
/**
|
|
94
|
+
* **1 USD = 1480 IQD → 1 IQD = 1/1480 USD
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* convertCurrency({
|
|
98
|
+
* amount: 100,
|
|
99
|
+
* from: 'USD',
|
|
100
|
+
* to: 'IQD',
|
|
101
|
+
* directRate: 1 / 1480,
|
|
102
|
+
* }) => 1
|
|
103
|
+
*/
|
|
104
|
+
/** Either **`directRate`** or **`baseCurrency` + **`quotes`** (not both shapes required on one union property set). */
|
|
105
|
+
export function convertCurrency(options) {
|
|
106
|
+
const { amount, from, to } = options;
|
|
107
|
+
if ('directRate' in options && options.directRate !== undefined)
|
|
108
|
+
return convertCurrencyWithDirectRate(amount, from, to, options.directRate);
|
|
109
|
+
if ('baseCurrency' in options && options.baseCurrency !== undefined && 'quotes' in options && options.quotes !== undefined)
|
|
110
|
+
return convertCurrencyViaBase(amount, from, to, options.baseCurrency, options.quotes);
|
|
111
|
+
throw new TypeError('convertCurrency: provide either { directRate } or { baseCurrency, quotes }');
|
|
112
|
+
}
|
|
113
|
+
/** Round after conversion (fraction digits ≥ 0). */
|
|
114
|
+
export function roundMoney(value, fractionDigits = 2) {
|
|
115
|
+
if (!Number.isFinite(value))
|
|
116
|
+
return Number.NaN;
|
|
117
|
+
const factor = 10 ** fractionDigits;
|
|
118
|
+
return Math.round(value * factor) / factor;
|
|
119
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const useFormatDate: () => {
|
|
2
|
+
toDDMMYY: (date: string | Date | null | undefined) => string;
|
|
3
|
+
toDDMMYYYY: (date: string | Date | null | undefined) => string;
|
|
4
|
+
toDateTime: (date: string | Date | null | undefined) => string;
|
|
5
|
+
toDateTime12h: (date: string | Date | null | undefined) => string;
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=useFormatDate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFormatDate.d.ts","sourceRoot":"","sources":["../src/useFormatDate.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa;qBAOE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,KAAG,MAAM;uBAgBvC,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,KAAG,MAAM;uBAgBzC,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,KAAG,MAAM;0BActC,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,KAAG,MAAM;CAsBzE,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export const useFormatDate = () => {
|
|
2
|
+
/**
|
|
3
|
+
* Format date to DD/MM/YY
|
|
4
|
+
* @param date Date string to format
|
|
5
|
+
* @returns Formatted date string with time (DD/MM/YY)
|
|
6
|
+
*/
|
|
7
|
+
function toDDMMYY(date) {
|
|
8
|
+
if (!date)
|
|
9
|
+
return '--/--/--';
|
|
10
|
+
const parsedDate = new Date(date);
|
|
11
|
+
const day = String(parsedDate.getDate()).padStart(2, '0');
|
|
12
|
+
const month = String(parsedDate.getMonth() + 1).padStart(2, '0');
|
|
13
|
+
const year = String(parsedDate.getFullYear()).slice(-2);
|
|
14
|
+
return `${day}/${month}/${year}`;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Format date to DD/MM/YYYY
|
|
18
|
+
* @param date Date string to format
|
|
19
|
+
* @returns Formatted date string with time (DD/MM/YYYY)
|
|
20
|
+
*/
|
|
21
|
+
function toDDMMYYYY(date) {
|
|
22
|
+
if (!date)
|
|
23
|
+
return '--/--/----';
|
|
24
|
+
const parsedDate = new Date(date);
|
|
25
|
+
const day = String(parsedDate.getDate()).padStart(2, '0');
|
|
26
|
+
const month = String(parsedDate.getMonth() + 1).padStart(2, '0');
|
|
27
|
+
const year = String(parsedDate.getFullYear());
|
|
28
|
+
return `${day}/${month}/${year}`;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Format date with time (used for audit logs and timestamps)
|
|
32
|
+
* @param date Date string to format
|
|
33
|
+
* @returns Formatted date string with time (YYYY/MM/DD HH:MM)
|
|
34
|
+
*/
|
|
35
|
+
function toDateTime(date) {
|
|
36
|
+
if (!date)
|
|
37
|
+
return '--/--/---- --:--';
|
|
38
|
+
const parsedDate = new Date(date);
|
|
39
|
+
const day = String(parsedDate.getDate()).padStart(2, '0');
|
|
40
|
+
const month = String(parsedDate.getMonth() + 1).padStart(2, '0');
|
|
41
|
+
const year = String(parsedDate.getFullYear());
|
|
42
|
+
const hours = String(parsedDate.getHours()).padStart(2, '0');
|
|
43
|
+
const minutes = String(parsedDate.getMinutes()).padStart(2, '0');
|
|
44
|
+
return `${day}/${month}/${year} ${hours}:${minutes}`;
|
|
45
|
+
}
|
|
46
|
+
function toDateTime12h(date) {
|
|
47
|
+
if (!date)
|
|
48
|
+
return '--/--/---- --:-- --';
|
|
49
|
+
const parsedDate = new Date(date);
|
|
50
|
+
const day = String(parsedDate.getDate()).padStart(2, '0');
|
|
51
|
+
const month = String(parsedDate.getMonth() + 1).padStart(2, '0');
|
|
52
|
+
const year = String(parsedDate.getFullYear());
|
|
53
|
+
const rawHours = parsedDate.getHours();
|
|
54
|
+
const ampm = rawHours >= 12 ? 'PM' : 'AM';
|
|
55
|
+
const hours = String(rawHours % 12 || 12).padStart(2, '0');
|
|
56
|
+
const minutes = String(parsedDate.getMinutes()).padStart(2, '0');
|
|
57
|
+
return `${day}/${month}/${year} ${hours}:${minutes} ${ampm}`;
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
toDDMMYY,
|
|
61
|
+
toDDMMYYYY,
|
|
62
|
+
toDateTime,
|
|
63
|
+
toDateTime12h
|
|
64
|
+
};
|
|
65
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useNumbersToWords.d.ts","sourceRoot":"","sources":["../src/useNumbersToWords.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB;mBAsHJ,MAAM,KAAG,MAAM;CAQxC,CAAA"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
export const useNumbersToWords = () => {
|
|
2
|
+
const ones = {
|
|
3
|
+
0: 'صفر', 1: 'واحد', 2: 'اثنان', 3: 'ثلاثة', 4: 'أربعة',
|
|
4
|
+
5: 'خمسة', 6: 'ستة', 7: 'سبعة', 8: 'ثمانية', 9: 'تسعة',
|
|
5
|
+
10: 'عشرة', 11: 'أحد عشر', 12: 'اثنى عشر',
|
|
6
|
+
};
|
|
7
|
+
const tens = {
|
|
8
|
+
1: 'عشر', 2: 'عشرون', 3: 'ثلاثون', 4: 'أربعون',
|
|
9
|
+
5: 'خمسون', 6: 'ستون', 7: 'سبعون', 8: 'ثمانون', 9: 'تسعون',
|
|
10
|
+
};
|
|
11
|
+
const hundreds = {
|
|
12
|
+
0: 'صفر', 1: 'مائة', 2: 'مئتان', 3: 'ثلاثمائة', 4: 'أربعمائة',
|
|
13
|
+
5: 'خمسمائة', 6: 'ستمائة', 7: 'سبعمائة', 8: 'ثمانمائة', 9: 'تسعمائة',
|
|
14
|
+
};
|
|
15
|
+
const thousands = { 1: 'ألف', 2: 'ألفان', 39: 'آلاف', 1199: 'ألفًا' };
|
|
16
|
+
const millions = { 1: 'مليون', 2: 'مليونان', 39: 'ملايين', 1199: 'مليونًا' };
|
|
17
|
+
const billions = { 1: 'مليار', 2: 'ملياران', 39: 'مليارات', 1199: 'مليارًا' };
|
|
18
|
+
const trillions = { 1: 'تريليون', 2: 'تريليونان', 39: 'تريليونات', 1199: 'تريليونًا' };
|
|
19
|
+
function getNth(number, first, end) {
|
|
20
|
+
let result = '';
|
|
21
|
+
for (let i = first; i <= end; i++)
|
|
22
|
+
result += String(number).charAt(i);
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
function getNthReverse(number, limit) {
|
|
26
|
+
let result = '';
|
|
27
|
+
let x = 1;
|
|
28
|
+
while (x !== limit) {
|
|
29
|
+
result = String(number).charAt(number.toString().length - x) + result;
|
|
30
|
+
x++;
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
function oneTen(number) {
|
|
35
|
+
let value = 'صفر';
|
|
36
|
+
if (number <= 12) {
|
|
37
|
+
value = ones[number] ?? 'صفر';
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
const first = getNth(number, 0, 0);
|
|
41
|
+
const second = getNth(number, 1, 1);
|
|
42
|
+
if (tens[+first] === 'عشر')
|
|
43
|
+
value = `${ones[+second]} ${tens[+first]}`;
|
|
44
|
+
else
|
|
45
|
+
value = `${ones[+second]} و${tens[+first]}`;
|
|
46
|
+
}
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
function hundred(number) {
|
|
50
|
+
while (number.toString().length !== 3)
|
|
51
|
+
number = '0' + number;
|
|
52
|
+
const first = +getNth(number, 0, 0);
|
|
53
|
+
let value = hundreds[first];
|
|
54
|
+
value = `${value} و${oneTen(parseInt(getNth(number, 1, 2)))}`;
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
function thousandsTrillions(one, two, three, eleven, diff, number, other) {
|
|
58
|
+
other = parseInt(other);
|
|
59
|
+
other = _tafqeet(other);
|
|
60
|
+
if (other === '')
|
|
61
|
+
other = 'صفر';
|
|
62
|
+
let value = '';
|
|
63
|
+
number = parseInt(String(number));
|
|
64
|
+
const len = number.toString().length;
|
|
65
|
+
if (len === 4 + diff) {
|
|
66
|
+
const o = parseInt(getNth(number, 0, 0));
|
|
67
|
+
if (o === 1)
|
|
68
|
+
value = `${one} و${other}`;
|
|
69
|
+
else if (o === 2)
|
|
70
|
+
value = `${two} و${other}`;
|
|
71
|
+
else
|
|
72
|
+
value = `${oneTen(o)} ${three} و${other}`;
|
|
73
|
+
}
|
|
74
|
+
else if (len === 5 + diff) {
|
|
75
|
+
const t = parseInt(getNth(number, 0, 1));
|
|
76
|
+
if (t === 10)
|
|
77
|
+
value = `${oneTen(t)} ${three} و${other}`;
|
|
78
|
+
else
|
|
79
|
+
value = `${oneTen(t)} ${eleven} و${other}`;
|
|
80
|
+
}
|
|
81
|
+
else if (len === 6 + diff) {
|
|
82
|
+
const h = parseInt(getNth(number, 0, 2));
|
|
83
|
+
const twoDigit = parseInt(getNth(number, 1, 2));
|
|
84
|
+
const th = twoDigit === 0 ? one : eleven;
|
|
85
|
+
value = `${hundred(h)} ${th} و${other}`;
|
|
86
|
+
}
|
|
87
|
+
return value;
|
|
88
|
+
}
|
|
89
|
+
function _tafqeet(number) {
|
|
90
|
+
let value = '';
|
|
91
|
+
number = parseInt(String(number));
|
|
92
|
+
if (number.toString().match(/^[0-9]+$/) !== null && number.toString().length <= 14) {
|
|
93
|
+
const len = number.toString().length;
|
|
94
|
+
if (len <= 2)
|
|
95
|
+
value = oneTen(number);
|
|
96
|
+
else if (len === 3)
|
|
97
|
+
value = hundred(number);
|
|
98
|
+
else if (len <= 6)
|
|
99
|
+
value = thousandsTrillions(thousands[1], thousands[2], thousands[39], thousands[1199], 0, number, getNthReverse(number, 4));
|
|
100
|
+
else if (len <= 9)
|
|
101
|
+
value = thousandsTrillions(millions[1], millions[2], millions[39], millions[1199], 3, number, getNthReverse(number, 7));
|
|
102
|
+
else if (len <= 12)
|
|
103
|
+
value = thousandsTrillions(billions[1], billions[2], billions[39], billions[1199], 6, number, getNthReverse(number, 10));
|
|
104
|
+
else
|
|
105
|
+
value = thousandsTrillions(trillions[1], trillions[2], trillions[39], trillions[1199], 9, number, getNthReverse(number, 13));
|
|
106
|
+
}
|
|
107
|
+
return value
|
|
108
|
+
.replace(/وصفر/g, '')
|
|
109
|
+
.replace(/وundefined/g, '')
|
|
110
|
+
.replace(/ +(?= )/g, '')
|
|
111
|
+
.replace(/صفر و/g, '')
|
|
112
|
+
.replace(/صفر/g, '')
|
|
113
|
+
.replace(/مئتان أ/, 'مائتا أ')
|
|
114
|
+
.replace(/مئتان م/, 'مائتا م');
|
|
115
|
+
}
|
|
116
|
+
function spell(value) {
|
|
117
|
+
if (!value || value === 0)
|
|
118
|
+
return '';
|
|
119
|
+
return _tafqeet(Math.round(Math.abs(value)));
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
spell
|
|
123
|
+
};
|
|
124
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dakkiin/eida",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"private": false,
|
|
6
|
+
"description": "Enjaz eida formatting utilities (dates, currency, Arabic number words)",
|
|
7
|
+
"license": "UNLICENSED",
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public",
|
|
10
|
+
"registry": "https://registry.npmjs.org/"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/3lawi964/packages.git",
|
|
15
|
+
"directory": "src/packages/@enjaz-eida"
|
|
16
|
+
},
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"main": "./dist/index.js",
|
|
24
|
+
"module": "./dist/index.js",
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsc",
|
|
31
|
+
"prepublishOnly": "npm run build"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"vue": "^3.5.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"typescript": "^5.9.3",
|
|
38
|
+
"vue": "^3.5.22"
|
|
39
|
+
}
|
|
40
|
+
}
|