@jarenjs/core 0.9.2 → 0.34.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.
Files changed (121) hide show
  1. package/ARCHITECTURE.md +229 -26
  2. package/README.md +64 -10
  3. package/dist/types/array.d.ts +13 -0
  4. package/dist/types/cache.d.ts +166 -0
  5. package/dist/types/chunk.d.ts +102 -0
  6. package/dist/types/color.d.ts +64 -0
  7. package/dist/types/convert/convert.d.ts +33 -0
  8. package/dist/types/convert/currency.d.ts +47 -0
  9. package/dist/types/convert/index.d.ts +9 -0
  10. package/dist/types/convert/registry.d.ts +55 -0
  11. package/dist/types/dates/civil.d.ts +146 -0
  12. package/dist/types/dates/duration.d.ts +83 -0
  13. package/dist/types/dates/format.d.ts +59 -0
  14. package/dist/types/dates/index.d.ts +4 -0
  15. package/dist/types/{dates.d.ts → dates/rfc3339.d.ts} +57 -3
  16. package/dist/types/errors.d.ts +77 -0
  17. package/dist/types/finance/amortization.d.ts +51 -0
  18. package/dist/types/finance/bond.d.ts +45 -0
  19. package/dist/types/finance/cashflow.d.ts +44 -0
  20. package/dist/types/finance/depreciation.d.ts +26 -0
  21. package/dist/types/finance/index.d.ts +16 -0
  22. package/dist/types/finance/indicators.d.ts +76 -0
  23. package/dist/types/finance/interest.d.ts +44 -0
  24. package/dist/types/finance/returns.d.ts +43 -0
  25. package/dist/types/finance/tvm.d.ts +50 -0
  26. package/dist/types/geo/angle.d.ts +4 -0
  27. package/dist/types/geo/bbox.d.ts +32 -0
  28. package/dist/types/geo/distance.d.ts +67 -0
  29. package/dist/types/geo/geohash.d.ts +63 -0
  30. package/dist/types/geo/geojson.d.ts +108 -0
  31. package/dist/types/geo/index-tree.d.ts +52 -0
  32. package/dist/types/geo/index.d.ts +11 -0
  33. package/dist/types/geo/mercator.d.ts +57 -0
  34. package/dist/types/geo/predicates.d.ts +44 -0
  35. package/dist/types/geo/ring.d.ts +80 -0
  36. package/dist/types/geo/simplify.d.ts +31 -0
  37. package/dist/types/geo/valid.d.ts +24 -0
  38. package/dist/types/geo/wkt.d.ts +16 -0
  39. package/dist/types/math/float64.d.ts +126 -3
  40. package/dist/types/math/format.d.ts +58 -0
  41. package/dist/types/math/index.d.ts +5 -0
  42. package/dist/types/math/mat4.d.ts +60 -0
  43. package/dist/types/math/project.d.ts +54 -0
  44. package/dist/types/math/solve.d.ts +67 -0
  45. package/dist/types/math/word.d.ts +82 -0
  46. package/dist/types/message.d.ts +52 -0
  47. package/dist/types/object.d.ts +151 -0
  48. package/dist/types/scan.d.ts +30 -0
  49. package/dist/types/schema.d.ts +24 -0
  50. package/dist/types/string.d.ts +96 -0
  51. package/dist/types/text/base64.d.ts +6 -4
  52. package/dist/types/text/email.d.ts +0 -1
  53. package/dist/types/text/host.d.ts +39 -8
  54. package/dist/types/text/i18n.d.ts +13 -1
  55. package/dist/types/text/index.d.ts +1 -0
  56. package/dist/types/text/misc.d.ts +15 -1
  57. package/dist/types/text/punycode.d.ts +45 -85
  58. package/docs/CONVERT.md +45 -0
  59. package/docs/DATES.md +78 -0
  60. package/docs/FINANCE.md +59 -0
  61. package/docs/GEO.md +114 -0
  62. package/docs/MATH.md +75 -0
  63. package/package.json +57 -4
  64. package/src/array.js +16 -0
  65. package/src/cache.js +206 -0
  66. package/src/chunk.js +159 -0
  67. package/src/color.js +125 -0
  68. package/src/convert/convert.js +59 -0
  69. package/src/convert/currency.js +74 -0
  70. package/src/convert/index.js +11 -0
  71. package/src/convert/registry.js +213 -0
  72. package/src/dates/civil.js +360 -0
  73. package/src/dates/duration.js +225 -0
  74. package/src/dates/format.js +238 -0
  75. package/src/dates/index.js +30 -0
  76. package/src/dates/rfc3339.js +621 -0
  77. package/src/errors.js +102 -0
  78. package/src/finance/amortization.js +50 -0
  79. package/src/finance/bond.js +100 -0
  80. package/src/finance/cashflow.js +122 -0
  81. package/src/finance/depreciation.js +54 -0
  82. package/src/finance/index.js +27 -0
  83. package/src/finance/indicators.js +207 -0
  84. package/src/finance/interest.js +63 -0
  85. package/src/finance/returns.js +90 -0
  86. package/src/finance/tvm.js +94 -0
  87. package/src/function.js +0 -2
  88. package/src/geo/angle.js +12 -0
  89. package/src/geo/bbox.js +80 -0
  90. package/src/geo/distance.js +155 -0
  91. package/src/geo/geohash.js +224 -0
  92. package/src/geo/geojson.js +361 -0
  93. package/src/geo/index-tree.js +294 -0
  94. package/src/geo/index.js +52 -0
  95. package/src/geo/mercator.js +124 -0
  96. package/src/geo/predicates.js +313 -0
  97. package/src/geo/ring.js +182 -0
  98. package/src/geo/simplify.js +130 -0
  99. package/src/geo/valid.js +142 -0
  100. package/src/geo/wkt.js +262 -0
  101. package/src/math/float64.js +228 -11
  102. package/src/math/format.js +157 -0
  103. package/src/math/index.js +5 -0
  104. package/src/math/mat4.js +131 -0
  105. package/src/math/project.js +49 -0
  106. package/src/math/solve.js +112 -0
  107. package/src/math/word.js +177 -0
  108. package/src/message.js +119 -0
  109. package/src/object.js +329 -0
  110. package/src/scan.js +42 -0
  111. package/src/schema.js +37 -0
  112. package/src/string.js +189 -0
  113. package/src/text/base64.js +15 -52
  114. package/src/text/email.js +0 -5
  115. package/src/text/host.js +515 -140
  116. package/src/text/i18n.js +13 -6
  117. package/src/text/identifiers.js +1 -1
  118. package/src/text/index.js +1 -0
  119. package/src/text/misc.js +81 -5
  120. package/src/text/punycode.js +235 -323
  121. package/src/dates.js +0 -371
package/src/text/i18n.js CHANGED
@@ -28,7 +28,6 @@ const HEBREW_GERSHAYIM = 0x05f4; // ״
28
28
  const KATAKANA_MIDDLE_DOT = 0x30fb; // ・
29
29
  const ZERO_WIDTH_JOINER = 0x200d; //
30
30
  const ZERO_WIDTH_NON_JOINER = 0x200c; //
31
- const VIRAMA = 0x094d; // ् (Devanagari Sign Virama)
32
31
 
33
32
  // Character category checks
34
33
  export function isLatinLowercaseL(code) {
@@ -99,11 +98,19 @@ export function isCombiningMark(code) {
99
98
  code === 0x0903; // Devanagari Sign Visarga
100
99
  }
101
100
 
102
- // Check contextual rules for a label
103
- export function checkContextualRules(label) {
104
- const chars = Array.from(label);
105
- const codes = chars.map(c => c.codePointAt(0));
106
-
101
+ /**
102
+ * Check the IDNA contextual rules for a label (RFC 5892 appendix A):
103
+ * the characters that are only permitted next to particular scripts.
104
+ *
105
+ * Takes the label's code points rather than the label, matching
106
+ * `checkDigitMixing` - callers validating a label have already decoded
107
+ * it, and decoding it a second time here was the only reason this
108
+ * needed the string at all.
109
+ *
110
+ * @param {number[]} codes - The label's Unicode code points
111
+ * @returns {boolean} True when every contextual rule holds
112
+ */
113
+ export function checkContextualRules(codes) {
107
114
  for (let i = 0; i < codes.length; i++) {
108
115
  const code = codes[i];
109
116
 
@@ -16,7 +16,7 @@ export function isValidIdentifier(str) {
16
16
  return /* str != null && */ CONST_REGEXP_IDENTIFIER.test(str);
17
17
  }
18
18
 
19
- const CONST_REGEXP_HTML_IDENTIFIER = /^[A-Za-z][\w\-\:\.]{0,30}$/;
19
+ const CONST_REGEXP_HTML_IDENTIFIER = /^[A-Za-z][\w\-:.]{0,30}$/;
20
20
  export function isValidHtmlIdentifier(str) {
21
21
  return /* str != null && */ CONST_REGEXP_HTML_IDENTIFIER.test(str);
22
22
  }
package/src/text/index.js CHANGED
@@ -9,3 +9,4 @@ export * from './i18n.js';
9
9
  export * from './identifiers.js';
10
10
  export * from './iregexp.js';
11
11
  export * from './misc.js';
12
+ export * from './punycode.js';
package/src/text/misc.js CHANGED
@@ -1,19 +1,95 @@
1
- const CONST_REGPEXP_ISBN10 = /^(?:ISBN(?:-10)?:?\ *((?=\d{1,5}([ -]?)\d{1,7}\2?\d{1,6}\2?\d)(?:\d\2*){9}[\dX]))$/i;
1
+ const CONST_REGPEXP_ISBN10 = /^(?:ISBN(?:-10)?:? *((?=\d{1,5}([ -]?)\d{1,7}\2?\d{1,6}\2?\d)(?:\d\2*){9}[\dX]))$/i;
2
2
  export function isValidISBN10(str) {
3
3
  return CONST_REGPEXP_ISBN10.test(str);
4
4
  }
5
5
 
6
- const CONST_REGEXP_ISBN13 = /^(?:ISBN(?:-13)?:?\ *(97(?:8|9)([ -]?)(?=\d{1,5}\2?\d{1,7}\2?\d{1,6}\2?\d)(?:\d\2*){9}\d))$/i;
6
+ const CONST_REGEXP_ISBN13 = /^(?:ISBN(?:-13)?:? *(97(?:8|9)([ -]?)(?=\d{1,5}\2?\d{1,7}\2?\d{1,6}\2?\d)(?:\d\2*){9}\d))$/i;
7
7
  export function isValidISBN13(str) {
8
8
  return CONST_REGEXP_ISBN13.test(str);
9
9
  }
10
10
 
11
- const CONST_REGEXP_COUNTRY_ALPHA2 = /^(AF|AX|AL|DZ|AS|AD|AO|AI|AQ|AG|AR|AM|AW|AU|AT|AZ|BS|BH|BD|BB|BY|BE|BZ|BJ|BM|BT|BO|BQ|BA|BW|BV|BR|IO|BN|BG|BF|BI|KH|CM|CA|CV|KY|CF|TD|CL|CN|CX|CC|CO|KM|CG|CD|CK|CR|CI|HR|CU|CW|CY|CZ|DK|DJ|DM|DO|EC|EG|SV|GQ|ER|EE|ET|FK|FO|FJ|FI|FR|GF|PF|TF|GA|GM|GE|DE|GH|GI|GR|GL|GD|GP|GU|GT|GG|GN|GW|GY|HT|HM|VA|HN|HK|HU|IS|IN|ID|IR|IQ|IE|IM|IL|IT|JM|JP|JE|JO|KZ|KE|KI|KP|KR|KW|KG|LA|LV|LB|LS|LR|LY|LI|LT|LU|MO|MK|MG|MW|MY|MV|ML|MT|MH|MQ|MR|MU|YT|MX|FM|MD|MC|MN|ME|MS|MA|MZ|MM|NA|NR|NP|NL|NC|NZ|NI|NE|NG|NU|NF|MP|NO|OM|PK|PW|PS|PA|PG|PY|PE|PH|PN|PL|PT|PR|QA|RE|RO|RU|RW|BL|SH|KN|LC|MF|PM|VC|WS|SM|ST|SA|SN|RS|SC|SL|SG|SX|SK|SI|SB|SO|ZA|GS|SS|ES|LK|SD|SR|SJ|SZ|SE|CH|SY|TW|TJ|TZ|TH|TL|TG|TK|TO|TT|TN|TR|TM|TC|TV|UG|UA|AE|GB|US|UM|UY|UZ|VU|VE|VN|VG|VI|WF|EH|YE|ZM|ZW|XK)/i;
11
+ // The 249 officially assigned ISO 3166-1 alpha-2 codes plus XK, the
12
+ // user-assigned code the EU institutions and the IBAN registry use for
13
+ // Kosovo. Matching is case-insensitive, like the other host/identifier
14
+ // testers here, even though ISO 3166-1 writes alpha-2 codes uppercase.
15
+ const CONST_REGEXP_COUNTRY_ALPHA2 = /^(?:AF|AX|AL|DZ|AS|AD|AO|AI|AQ|AG|AR|AM|AW|AU|AT|AZ|BS|BH|BD|BB|BY|BE|BZ|BJ|BM|BT|BO|BQ|BA|BW|BV|BR|IO|BN|BG|BF|BI|KH|CM|CA|CV|KY|CF|TD|CL|CN|CX|CC|CO|KM|CG|CD|CK|CR|CI|HR|CU|CW|CY|CZ|DK|DJ|DM|DO|EC|EG|SV|GQ|ER|EE|ET|FK|FO|FJ|FI|FR|GF|PF|TF|GA|GM|GE|DE|GH|GI|GR|GL|GD|GP|GU|GT|GG|GN|GW|GY|HT|HM|VA|HN|HK|HU|IS|IN|ID|IR|IQ|IE|IM|IL|IT|JM|JP|JE|JO|KZ|KE|KI|KP|KR|KW|KG|LA|LV|LB|LS|LR|LY|LI|LT|LU|MO|MK|MG|MW|MY|MV|ML|MT|MH|MQ|MR|MU|YT|MX|FM|MD|MC|MN|ME|MS|MA|MZ|MM|NA|NR|NP|NL|NC|NZ|NI|NE|NG|NU|NF|MP|NO|OM|PK|PW|PS|PA|PG|PY|PE|PH|PN|PL|PT|PR|QA|RE|RO|RU|RW|BL|SH|KN|LC|MF|PM|VC|WS|SM|ST|SA|SN|RS|SC|SL|SG|SX|SK|SI|SB|SO|ZA|GS|SS|ES|LK|SD|SR|SJ|SZ|SE|CH|SY|TW|TJ|TZ|TH|TL|TG|TK|TO|TT|TN|TR|TM|TC|TV|UG|UA|AE|GB|US|UM|UY|UZ|VU|VE|VN|VG|VI|WF|EH|YE|ZM|ZW|XK)$/i;
12
16
  export function isValidCountryAlpha2(str) {
13
17
  return CONST_REGEXP_COUNTRY_ALPHA2.test(str);
14
18
  }
15
19
 
16
- const CONST_REGEXP_IBAN = /^([A-Z]{2}[ '+'\\\\'+'-]?[0-9]{2})(?=(?:[ '+'\\\\'+'-]?[A-Z0-9]){9,30}\$)((?:[ '+'\\\\'+'-]?[A-Z0-9]{3,5}){2,7})([ '+'\\\\'+'-]?[A-Z0-9]{1,3})?\$/i;
20
+ /**
21
+ * Total length of the electronic-format IBAN per country, from the ISO
22
+ * 13616 registry maintained by SWIFT. A country absent from the registry
23
+ * has no IBAN standard to be well-formed against, so its codes are
24
+ * rejected rather than length-checked loosely - which is what makes the
25
+ * length half of this test meaningful at all.
26
+ */
27
+ const IBAN_LENGTHS = {
28
+ AD: 24, AE: 23, AL: 28, AT: 20, AZ: 28, BA: 20, BE: 16, BG: 22, BH: 22,
29
+ BI: 27, BR: 29, BY: 28, CH: 21, CR: 22, CY: 28, CZ: 24, DE: 22, DJ: 27,
30
+ DK: 18, DO: 28, EE: 20, EG: 29, ES: 24, FI: 18, FK: 18, FO: 18, FR: 27,
31
+ GB: 22, GE: 22, GI: 23, GL: 18, GR: 27, GT: 28, HN: 28, HR: 21, HU: 28,
32
+ IE: 22, IL: 23, IQ: 23, IS: 26, IT: 27, JO: 30, KW: 30, KZ: 20, LB: 28,
33
+ LC: 32, LI: 21, LT: 20, LU: 20, LV: 21, LY: 25, MC: 27, MD: 24, ME: 22,
34
+ MK: 19, MN: 20, MR: 27, MT: 31, MU: 30, NI: 28, NL: 18, NO: 15, OM: 23,
35
+ PK: 24, PL: 28, PS: 29, PT: 25, QA: 29, RO: 24, RS: 22, RU: 33, SA: 24,
36
+ SC: 31, SD: 18, SE: 24, SI: 19, SK: 24, SM: 27, SO: 23, ST: 25, SV: 28,
37
+ TL: 23, TN: 24, TR: 26, UA: 29, VA: 22, VG: 24, XK: 20, YE: 30,
38
+ };
39
+
40
+ /**
41
+ * Validate an International Bank Account Number (ISO 13616).
42
+ *
43
+ * Three independent things have to hold, and a string that satisfies only
44
+ * the first two is the common counterfeit: the country's registered
45
+ * length, the alphanumeric body shape, and the ISO 7064 MOD 97-10 check
46
+ * digits. Both written forms are accepted - the compact electronic format
47
+ * (`NL91ABNA0417164300`) and the ISO 13616-2 print format, which groups
48
+ * into fours with single spaces (`NL91 ABNA 0417 1643 00`). Lowercase is
49
+ * accepted for the same reason the other testers here accept it.
50
+ *
51
+ * @param {string} str - The candidate IBAN
52
+ * @returns {boolean} True when the string is a well-formed IBAN
53
+ */
17
54
  export function isValidIBAN(str) {
18
- return CONST_REGEXP_IBAN.test(str);
55
+ const len = str.length;
56
+ if (len < 15 || len > 34 + 8) return false;
57
+
58
+ // The print format puts a single space after every fourth character, so
59
+ // the compact length determines the spaced length exactly. Deciding the
60
+ // written form up front turns the compact position -> source index map
61
+ // into arithmetic, and keeps the whole test allocation-free.
62
+ const spaced = str.charCodeAt(4) === 0x20;
63
+ const n = spaced ? len - ((len / 5) | 0) : len;
64
+ if (n < 15 || n > 34) return false;
65
+ if (spaced && len !== n + ((n - 1) / 4 | 0)) return false;
66
+
67
+ // Country code and check digits: two letters then two digits.
68
+ const c0 = str.charCodeAt(0) & ~0x20; // uppercase the ASCII letter
69
+ const c1 = str.charCodeAt(1) & ~0x20;
70
+ if (c0 < 0x41 || c0 > 0x5A || c1 < 0x41 || c1 > 0x5A) return false;
71
+ const registered = IBAN_LENGTHS[String.fromCharCode(c0, c1)];
72
+ if (registered !== n) return false;
73
+
74
+ // ISO 7064 MOD 97-10 over the rearranged string: the body (compact
75
+ // positions 4..n-1) followed by the country code and check digits, with
76
+ // letters expanded to their two-digit values A=10 .. Z=35. A running
77
+ // remainder keeps every intermediate under 9735, so this stays exact in
78
+ // a Number without a BigInt or an intermediate string.
79
+ let rem = 0;
80
+ for (let p = 0; p < n; p++) {
81
+ const q = p + 4 < n ? p + 4 : p + 4 - n;
82
+ const i = spaced ? q + ((q / 4) | 0) : q;
83
+ const code = str.charCodeAt(i);
84
+ if (code >= 0x30 && code <= 0x39) {
85
+ rem = (rem * 10 + (code - 0x30)) % 97;
86
+ }
87
+ else {
88
+ const upper = code & ~0x20; // uppercase the ASCII letter
89
+ if (upper < 0x41 || upper > 0x5A) return false;
90
+ if (q === 2 || q === 3) return false; // the check digits must be digits
91
+ rem = (rem * 100 + (upper - 55)) % 97;
92
+ }
93
+ }
94
+ return rem === 1;
19
95
  }