jsfunx 1.1.2 → 1.2.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 (4) hide show
  1. package/README.md +20 -16
  2. package/jsfunx.cjs +124 -113
  3. package/jsfunx.mjs +129 -113
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -9,13 +9,13 @@ The main reason why this library was created is to:
9
9
  ### use
10
10
 
11
11
  ```js
12
- import { isType, number } from "jsfunx"; // ESM
12
+ import { isType, number, useStrict } from "jsfunx"; // ESM
13
13
 
14
14
  // or
15
15
 
16
16
  // "use strict"; // CJS
17
17
 
18
- // const { isType, number } = require("jsfunx"); // CJS
18
+ // const { isType, number, useStrict } = require("jsfunx"); // CJS
19
19
 
20
20
  /**
21
21
  * Adds two numbers together and returns the result.
@@ -27,8 +27,9 @@ import { isType, number } from "jsfunx"; // ESM
27
27
  */
28
28
 
29
29
  function add(num1, num2) {
30
- // 35 char
30
+ useStrict(add, arguments);
31
31
 
32
+ // 35 char
32
33
  if (isType([num1, num2], number)) {
33
34
  return num1 + num2;
34
35
  }
@@ -59,7 +60,6 @@ console.log(add(Number(1), Number(3)));
59
60
 
60
61
  function add(num1, num2) {
61
62
  // 59 char
62
-
63
63
  if (typeof num1 === "number" && typeof num2 === "number") {
64
64
  return num1 + num2;
65
65
  }
@@ -77,13 +77,13 @@ console.log(add(Number(1), Number(3)));
77
77
  ### and
78
78
 
79
79
  ```js
80
- import { isType, number, string } from "jsfunx"; // ESM
80
+ import { isType, number, string, useStrict } from "jsfunx"; // ESM
81
81
 
82
82
  // or
83
83
 
84
84
  // "use strict"; // CJS
85
85
 
86
- // const { isType, number, string } = require("jsfunx"); // CJS
86
+ // const { isType, number, string, useStrict } = require("jsfunx"); // CJS
87
87
 
88
88
  /**
89
89
  * Prints a message with the given name and age.
@@ -95,8 +95,9 @@ import { isType, number, string } from "jsfunx"; // ESM
95
95
  */
96
96
 
97
97
  function fun(name, age) {
98
- // 44 char
98
+ useStrict(fun, arguments);
99
99
 
100
+ // 44 char
100
101
  if (isType([name, age], [string, number])) {
101
102
  console.log(`your name is ${name} and your age is ${age}`);
102
103
  return;
@@ -128,7 +129,6 @@ fun(String("mohamed"), Number(23));
128
129
 
129
130
  function fun(name, age) {
130
131
  // 58 char
131
-
132
132
  if (typeof name === "string" && typeof age === "number") {
133
133
  console.log(`your name is ${name} and your age is ${age}`);
134
134
  return;
@@ -147,13 +147,13 @@ fun(String("mohamed"), Number(23));
147
147
  ### and
148
148
 
149
149
  ```js
150
- import { instancesof } from "jsfunx"; // ESM
150
+ import { instancesof, useStrict } from "jsfunx"; // ESM
151
151
 
152
152
  // or
153
153
 
154
154
  // "use strict"; // CJS
155
155
 
156
- // const { instancesof } = require("jsfunx"); // CJS
156
+ // const { instancesof, useStrict } = require("jsfunx"); // CJS
157
157
 
158
158
  /**
159
159
  * Adds two numbers together and returns the result.
@@ -165,8 +165,9 @@ import { instancesof } from "jsfunx"; // ESM
165
165
  */
166
166
 
167
167
  function add(num1, num2) {
168
- // 40 char
168
+ useStrict(add, arguments);
169
169
 
170
+ // 40 char
170
171
  if (instancesof([num1, num2], Number)) {
171
172
  return new Number(num1 + num2);
172
173
  }
@@ -193,7 +194,6 @@ console.log(add(new Number(1), new Number(3)));
193
194
 
194
195
  function add(num1, num2) {
195
196
  // 55 char
196
-
197
197
  if (num1 instanceof Number && num2 instanceof Number) {
198
198
  return new Number(num1 + num2);
199
199
  }
@@ -207,13 +207,13 @@ console.log(add(new Number(1), new Number(3)));
207
207
  ### and
208
208
 
209
209
  ```js
210
- import { instancesof } from "jsfunx"; // ESM
210
+ import { instancesof, useStrict } from "jsfunx"; // ESM
211
211
 
212
212
  // or
213
213
 
214
214
  // "use strict"; // CJS
215
215
 
216
- // const { instancesof } = require("jsfunx"); // CJS
216
+ // const { instancesof, useStrict } = require("jsfunx"); // CJS
217
217
 
218
218
  /**
219
219
  * Prints a message with the given name and age.
@@ -225,8 +225,9 @@ import { instancesof } from "jsfunx"; // ESM
225
225
  */
226
226
 
227
227
  function fun(name, age) {
228
- // 49 char
228
+ useStrict(fun, arguments);
229
229
 
230
+ // 49 char
230
231
  if (instancesof([name, age], [String, Number])) {
231
232
  console.log(`your name is ${name} and your age is ${age}`);
232
233
  return;
@@ -254,7 +255,6 @@ fun(new String("mohamed"), new Number(23));
254
255
 
255
256
  function fun(name, age) {
256
257
  // 54 char
257
-
258
258
  if (name instanceof String && age instanceof Number) {
259
259
  console.log(`your name is ${name} and your age is ${age}`);
260
260
  return;
@@ -268,6 +268,10 @@ fun(new String("mohamed"), new Number(23));
268
268
 
269
269
  but not just this there is other funcs you can see the source code and check all the tests in the main fun.
270
270
 
271
+ ## Note:
272
+
273
+ useStrict() was used to enforce strict argument passing in functions.
274
+
271
275
  ## Installation
272
276
 
273
277
  You can install `jsfunx` via npm:
package/jsfunx.cjs CHANGED
@@ -153,9 +153,9 @@ const undef = "undefined";
153
153
  *
154
154
  * @param {* | Array<*>} data - The value or array of values to check.
155
155
  * @param {* | Array<*>} dataType - The expected type or array of expected types.
156
- * @param {"and" | "or"} logic - Logic mode: `"and"` requires all matches, `"or"` allows any match.
157
- * @param {boolean} match - Whether to compare type names strictly or loosely.
158
- * @param {boolean} strict - If `true`, enforces strict comparison rules.
156
+ * @param {("and" | "or") | String} logic - Logic mode: `"and"` requires all matches, `"or"` allows any match.
157
+ * @param {boolean | Boolean} match - Whether to compare type names strictly or loosely.
158
+ * @param {boolean | Boolean} strict - If `true`, enforces strict comparison rules.
159
159
  * @returns {boolean} `true` if the data matches the expected type(s) according to the given logic, otherwise `false`.
160
160
  */
161
161
 
@@ -783,9 +783,9 @@ function checkType(data, dataType, logic, match, strict) {
783
783
  * @template T - The instance type returned by the constructor(s).
784
784
  * @param {* | Array<*>} objs - The object or array of objects to test.
785
785
  * @param {(new (...args: any[]) => T) | Array<new (...args: any[]) => T>} type - The constructor or list of constructors to test against.
786
- * @param {"and" | "or"} logic - Logic mode: `"and"` requires all matches, `"or"` allows any match.
787
- * @param {boolean} match - Whether to compare classes names strictly or loosely.
788
- * @param {boolean} strict - If `true`, enables strict comparison behavior.
786
+ * @param {("and" | "or") | String} logic - Logic mode: `"and"` requires all matches, `"or"` allows any match.
787
+ * @param {boolean | Boolean} match - Whether to compare classes names strictly or loosely.
788
+ * @param {boolean | Boolean} strict - If `true`, enables strict comparison behavior.
789
789
  * @returns {boolean} `true` if the provided object(s) match the given type(s) according to the chosen logic, otherwise `false`.
790
790
  */
791
791
 
@@ -1292,9 +1292,9 @@ function echo(data) {
1292
1292
  * @template T - The instance type returned by the constructor(s).
1293
1293
  * @param {*|Array<*>} objs - The object or array of objects to test.
1294
1294
  * @param {(new (...args: any[]) => T) | Array<new (...args: any[]) => T>} type - The constructor or list of constructors to test against.
1295
- * @param {"and" | "or" | boolean} logic_or_match - Logic mode: `"and"` requires all matches, `"or"` allows any match.
1296
- * @param {boolean} match_or_strict - Whether to compare classes names strictly or loosely.
1297
- * @param {boolean} strict - If `true`, enables strict comparison behavior.
1295
+ * @param {("and" | "or") | String | (boolean | Boolean)} logic_or_match - Logic mode: `"and"` requires all matches, `"or"` allows any match.
1296
+ * @param {boolean | Boolean} match_or_strict - Whether to compare classes names strictly or loosely.
1297
+ * @param {boolean | Boolean} strict - If `true`, enables strict comparison behavior.
1298
1298
  * @returns {boolean} `true` if the provided object(s) match the given type(s) according to the chosen logic, otherwise `false`.
1299
1299
  */
1300
1300
 
@@ -1333,20 +1333,9 @@ function instancesof(
1333
1333
 
1334
1334
  // ================================================================
1335
1335
 
1336
- if (len === 3)
1337
- if (checkType(arguments[2], boolean) || arguments[2] instanceof Boolean)
1338
- return isinstancesof(objs, type, and, logic_or_match, strict);
1339
-
1340
- if (len === 4) {
1341
- if (
1342
- not(checkType(arguments[3], boolean)) &&
1343
- not(arguments[3] instanceof Boolean)
1344
- )
1345
- throw new TypeError("forth argument must be true or false");
1346
-
1347
- if (checkType(arguments[2], boolean) || arguments[2] instanceof Boolean)
1336
+ if (len > 2 && len < 5)
1337
+ if (checkType(logic_or_match, boolean) || logic_or_match instanceof Boolean)
1348
1338
  return isinstancesof(objs, type, and, logic_or_match, match_or_strict);
1349
- }
1350
1339
 
1351
1340
  return isinstancesof(objs, type, logic_or_match, match_or_strict, strict);
1352
1341
  }
@@ -1380,9 +1369,9 @@ function isinstance(obj, cls) {
1380
1369
  * @template T - The instance type returned by the constructor(s).
1381
1370
  * @param {*|Array<*>} objs - The object or array of objects to test.
1382
1371
  * @param {(new (...args: any[]) => T) | Array<new (...args: any[]) => T>} type - The constructor or list of constructors to test against.
1383
- * @param {"and" | "or" | boolean} logic_or_match - Logic mode: `"and"` requires all matches, `"or"` allows any match.
1384
- * @param {boolean} match_or_strict - Whether to compare classes names strictly or loosely.
1385
- * @param {boolean} strict - If `true`, enables strict comparison behavior.
1372
+ * @param {("and" | "or") | String | (boolean | Boolean)} logic_or_match - Logic mode: `"and"` requires all matches, `"or"` allows any match.
1373
+ * @param {boolean | Boolean} match_or_strict - Whether to compare classes names strictly or loosely.
1374
+ * @param {boolean | Boolean} strict - If `true`, enables strict comparison behavior.
1386
1375
  * @returns {boolean} `true` if the provided object(s) match the given type(s) according to the chosen logic, otherwise `false`.
1387
1376
  */
1388
1377
 
@@ -1405,9 +1394,9 @@ function isinstances(
1405
1394
  *
1406
1395
  * @param {* | Array<*>} data - The value or array of values to check.
1407
1396
  * @param {* | Array<*>} dataType - The expected type or array of expected types.
1408
- * @param {"and" | "or" | boolean} logic_or_match - Logic mode: `"and"` requires all matches, `"or"` allows any match.
1409
- * @param {boolean} match_or_strict - Whether to compare type names strictly or loosely.
1410
- * @param {boolean} strict - If `true`, enforces strict comparison rules.
1397
+ * @param {("and" | "or") | String | (boolean | Boolean)} logic_or_match - Logic mode: `"and"` requires all matches, `"or"` allows any match.
1398
+ * @param {boolean | Boolean} match_or_strict - Whether to compare type names strictly or loosely.
1399
+ * @param {boolean | Boolean} strict - If `true`, enforces strict comparison rules.
1411
1400
  * @returns {boolean} `true` if the data matches the expected type(s) according to the given logic, otherwise `false`.
1412
1401
  */
1413
1402
 
@@ -1446,20 +1435,9 @@ function isType(
1446
1435
 
1447
1436
  // ================================================================
1448
1437
 
1449
- if (len === 3)
1450
- if (checkType(arguments[2], boolean) || arguments[2] instanceof Boolean)
1451
- return checkType(data, dataType, and, logic_or_match, strict);
1452
-
1453
- if (len === 4) {
1454
- if (
1455
- not(checkType(arguments[3], boolean)) &&
1456
- not(arguments[3] instanceof Boolean)
1457
- )
1458
- throw new TypeError("forth argument must be true or false");
1459
-
1460
- if (checkType(arguments[2], boolean) || arguments[2] instanceof Boolean)
1438
+ if (len > 2 && len < 5)
1439
+ if (checkType(logic_or_match, boolean) || logic_or_match instanceof Boolean)
1461
1440
  return checkType(data, dataType, and, logic_or_match, match_or_strict);
1462
- }
1463
1441
 
1464
1442
  return checkType(data, dataType, logic_or_match, match_or_strict, strict);
1465
1443
  }
@@ -1566,10 +1544,14 @@ function log(...data) {
1566
1544
  */
1567
1545
 
1568
1546
  function not(obj) {
1569
- if (arguments.length === 0)
1570
- throw new TypeError("not() takes exactly one argument (0 given)");
1547
+ /** @type {number} */
1548
+
1549
+ let len = arguments.length;
1550
+
1551
+ if (len !== 1)
1552
+ throw new TypeError(`not() takes exactly one argument (${len} given)`);
1571
1553
 
1572
- if (obj instanceof Boolean) return obj == false;
1554
+ if (obj instanceof Boolean) return obj.valueOf() === false;
1573
1555
 
1574
1556
  return obj?.length === 0 || !obj; // handling the object case
1575
1557
  }
@@ -1624,6 +1606,89 @@ function puts(...data) {
1624
1606
  console.log(...data);
1625
1607
  }
1626
1608
 
1609
+ /**
1610
+ * Validates function arguments strictly at runtime.
1611
+ *
1612
+ * Ensures that:
1613
+ * 1. `useStrict` is called with exactly three arguments:
1614
+ * - `func`: the function to validate against
1615
+ * - `args`: an array or array-like object of arguments intended for `func`
1616
+ * - `optional`: optional arguments number in the function
1617
+ * 2. `func` is a function.
1618
+ * 3. `args` is array-like.
1619
+ * 4. `optional` is a number.
1620
+ * 5. The number of elements in `args` greater than or equal the number of parameters `func` expects.
1621
+ * 6. The number of elements in `args` less than or equal the number of parameters `func` + `optional` expects.
1622
+ *
1623
+ * @param {Function} func - The function whose arguments are being validated.
1624
+ * @param {Array|IArguments} args - The array-like object of arguments to check against the function's parameter count.
1625
+ * @param {number | Number} optional - default arguments number in the function.
1626
+ * @param {boolean | Boolean} postArgs - extra argument(s) after positional and optional ones `...args: any[]`.
1627
+ * @throws {TypeError} If called with a number of arguments less than 2.
1628
+ * @throws {TypeError} If called with a number of arguments greater than 3.
1629
+ * @throws {TypeError} If `func` is not a function.
1630
+ * @throws {TypeError} If `args` is not array-like.
1631
+ * @throws {TypeError} If `optional` is a negative number or not a number at all.
1632
+ * @throws {TypeError} If the length of `args` is less than the parameters number of `func`.
1633
+ * @throws {TypeError} If the length of `args` is greater than the parameters number of `func` + `optional`.
1634
+ * @returns {void} This function does not return a value.
1635
+ */
1636
+
1637
+ function strict(func, args, optional, postArgs) {
1638
+ if (!(func instanceof Function))
1639
+ throw new TypeError("first argument must be a function");
1640
+
1641
+ if (typeof args !== "object" || typeof args.length !== "number")
1642
+ throw new TypeError("second argument must be array-like");
1643
+
1644
+ if (
1645
+ (typeof optional !== "number" && !(optional instanceof Number)) ||
1646
+ optional < 0
1647
+ )
1648
+ throw new TypeError("third argument must be a positive number");
1649
+
1650
+ /** @type {string} */
1651
+
1652
+ const funcName = func.name;
1653
+
1654
+ /** @type {number} */
1655
+
1656
+ const paramsNumber = func.length;
1657
+
1658
+ /** @type {number} */
1659
+
1660
+ const argsNumber = args.length;
1661
+
1662
+ if (argsNumber < paramsNumber)
1663
+ throw new TypeError(
1664
+ `${funcName}() takes ${paramsNumber} positional argument(s) but ${argsNumber} were given`
1665
+ );
1666
+
1667
+ if (not(postArgs))
1668
+ if (argsNumber > paramsNumber + optional) {
1669
+ if (paramsNumber > 0 && optional > 0)
1670
+ throw new TypeError(
1671
+ `${funcName}() takes ${
1672
+ paramsNumber + optional
1673
+ } arguments in total but ${argsNumber} were given`
1674
+ );
1675
+
1676
+ if (paramsNumber > 0)
1677
+ throw new TypeError(
1678
+ `${funcName}() takes ${paramsNumber} positional argument(s) in total but ${argsNumber} were given`
1679
+ );
1680
+
1681
+ if (optional > 0)
1682
+ throw new TypeError(
1683
+ `${funcName}() takes ${optional} optional argument(s) in total but ${argsNumber} were given`
1684
+ );
1685
+
1686
+ throw new TypeError(
1687
+ `${funcName}() takes no argument(s) but ${argsNumber} were given`
1688
+ );
1689
+ }
1690
+ }
1691
+
1627
1692
  /**
1628
1693
  * Returns the JavaScript type of a value using the `typeof` operator.
1629
1694
  *
@@ -1704,31 +1769,14 @@ function typesof(...objs) {
1704
1769
  /**
1705
1770
  * Validates function arguments strictly at runtime.
1706
1771
  *
1707
- * Ensures that:
1708
- * 1. `useStrict` is called with exactly three arguments:
1709
- * - `func`: the function to validate against
1710
- * - `args`: an array or array-like object of arguments intended for `func`
1711
- * - `optional`: optional arguments number in the function
1712
- * 2. `func` is a function.
1713
- * 3. `args` is array-like.
1714
- * 4. `optional` is a number.
1715
- * 5. The number of elements in `args` greater than or equal the number of parameters `func` expects.
1716
- * 6. The number of elements in `args` less than or equal the number of parameters `func` + `optional` expects.
1717
- *
1718
1772
  * @param {Function} func - The function whose arguments are being validated.
1719
1773
  * @param {Array|IArguments} args - The array-like object of arguments to check against the function's parameter count.
1720
- * @param {number} optional - default arguments number in the function.
1721
- * @throws {TypeError} If called with a number of arguments less than 2.
1722
- * @throws {TypeError} If called with a number of arguments greater than 3.
1723
- * @throws {TypeError} If `func` is not a function.
1724
- * @throws {TypeError} If `args` is not array-like.
1725
- * @throws {TypeError} If `optional` is a negative number or not a number at all.
1726
- * @throws {TypeError} If the length of `args` is less than the parameters number of `func`.
1727
- * @throws {TypeError} If the length of `args` is greater than the parameters number of `func` + `optional`.
1774
+ * @param {number | Number} optional_or_postArgs - default arguments number in the function.
1775
+ * @param {boolean | Boolean} postArgs - extra argument(s) after positional and optional ones `...args: any[]`.
1728
1776
  * @returns {void} This function does not return a value.
1729
1777
  */
1730
1778
 
1731
- function useStrict(func, args, optional = 0) {
1779
+ function useStrict(func, args, optional_or_postArgs = 0, postArgs = false) {
1732
1780
  /** @type {number} */
1733
1781
 
1734
1782
  const len = arguments.length;
@@ -1740,59 +1788,22 @@ function useStrict(func, args, optional = 0) {
1740
1788
  : "useStrict() missing 2 required arguments: 'func' and 'args'"
1741
1789
  );
1742
1790
 
1743
- if (len > 3)
1744
- throw TypeError(
1745
- `useStrict() takes 3 arguments in total but ${len} were given`
1746
- );
1747
-
1748
- if (!(func instanceof Function))
1749
- throw TypeError("first argument must be a function");
1750
-
1751
- if (typeof args !== "object" || typeof args.length !== "number")
1752
- throw TypeError("second argument must be array-like");
1753
-
1754
- if (typeof optional !== "number" || optional < 0)
1755
- throw TypeError("third argument must be a positive number");
1756
-
1757
- /** @type {string} */
1758
-
1759
- const funcName = func.name;
1760
-
1761
- /** @type {number} */
1762
-
1763
- const paramsNumber = func.length;
1764
-
1765
- /** @type {number} */
1766
-
1767
- const argsNumber = args.length;
1768
-
1769
- if (argsNumber < paramsNumber)
1770
- throw TypeError(
1771
- `${funcName}() takes ${paramsNumber} positional argument(s) but ${argsNumber} were given`
1791
+ if (len > 4)
1792
+ throw new TypeError(
1793
+ `useStrict() takes 4 arguments in total but ${len} were given`
1772
1794
  );
1773
1795
 
1774
- if (argsNumber > paramsNumber + optional) {
1775
- if (paramsNumber > 0 && optional > 0)
1776
- throw TypeError(
1777
- `${funcName}() takes ${
1778
- paramsNumber + optional
1779
- } arguments in total but ${argsNumber} were given`
1780
- );
1781
-
1782
- if (paramsNumber > 0)
1783
- throw TypeError(
1784
- `${funcName}() takes ${paramsNumber} positional argument(s) in total but ${argsNumber} were given`
1785
- );
1786
-
1787
- if (optional > 0)
1788
- throw TypeError(
1789
- `${funcName}() takes ${optional} optional argument(s) in total but ${argsNumber} were given`
1790
- );
1796
+ if (len === 3) {
1797
+ if (
1798
+ typeof optional_or_postArgs === "boolean" ||
1799
+ optional_or_postArgs instanceof Boolean
1800
+ )
1801
+ strict(func, args, 0, optional_or_postArgs);
1791
1802
 
1792
- throw TypeError(
1793
- `${funcName}() takes no argument(s) but ${argsNumber} were given`
1794
- );
1803
+ return;
1795
1804
  }
1805
+
1806
+ strict(func, args, optional_or_postArgs, postArgs);
1796
1807
  }
1797
1808
 
1798
1809
  /**
package/jsfunx.mjs CHANGED
@@ -157,9 +157,9 @@ export const undef = "undefined";
157
157
  *
158
158
  * @param {* | Array<*>} data - The value or array of values to check.
159
159
  * @param {* | Array<*>} dataType - The expected type or array of expected types.
160
- * @param {"and" | "or"} logic - Logic mode: `"and"` requires all matches, `"or"` allows any match.
161
- * @param {boolean} match - Whether to compare type names strictly or loosely.
162
- * @param {boolean} strict - If `true`, enforces strict comparison rules.
160
+ * @param {("and" | "or") | String} logic - Logic mode: `"and"` requires all matches, `"or"` allows any match.
161
+ * @param {boolean | Boolean} match - Whether to compare type names strictly or loosely.
162
+ * @param {boolean | Boolean} strict - If `true`, enforces strict comparison rules.
163
163
  * @returns {boolean} `true` if the data matches the expected type(s) according to the given logic, otherwise `false`.
164
164
  */
165
165
 
@@ -787,9 +787,9 @@ function checkType(data, dataType, logic, match, strict) {
787
787
  * @template T - The instance type returned by the constructor(s).
788
788
  * @param {* | Array<*>} objs - The object or array of objects to test.
789
789
  * @param {(new (...args: any[]) => T) | Array<new (...args: any[]) => T>} type - The constructor or list of constructors to test against.
790
- * @param {"and" | "or"} logic - Logic mode: `"and"` requires all matches, `"or"` allows any match.
791
- * @param {boolean} match - Whether to compare classes names strictly or loosely.
792
- * @param {boolean} strict - If `true`, enables strict comparison behavior.
790
+ * @param {("and" | "or") | String} logic - Logic mode: `"and"` requires all matches, `"or"` allows any match.
791
+ * @param {boolean | Boolean} match - Whether to compare classes names strictly or loosely.
792
+ * @param {boolean | Boolean} strict - If `true`, enables strict comparison behavior.
793
793
  * @returns {boolean} `true` if the provided object(s) match the given type(s) according to the chosen logic, otherwise `false`.
794
794
  */
795
795
 
@@ -1296,9 +1296,9 @@ export function echo(data) {
1296
1296
  * @template T - The instance type returned by the constructor(s).
1297
1297
  * @param {*|Array<*>} objs - The object or array of objects to test.
1298
1298
  * @param {(new (...args: any[]) => T) | Array<new (...args: any[]) => T>} type - The constructor or list of constructors to test against.
1299
- * @param {"and" | "or" | boolean} logic_or_match - Logic mode: `"and"` requires all matches, `"or"` allows any match.
1300
- * @param {boolean} match_or_strict - Whether to compare classes names strictly or loosely.
1301
- * @param {boolean} strict - If `true`, enables strict comparison behavior.
1299
+ * @param {("and" | "or") | String | (boolean | Boolean)} logic_or_match - Logic mode: `"and"` requires all matches, `"or"` allows any match.
1300
+ * @param {boolean | Boolean} match_or_strict - Whether to compare classes names strictly or loosely.
1301
+ * @param {boolean | Boolean} strict - If `true`, enables strict comparison behavior.
1302
1302
  * @returns {boolean} `true` if the provided object(s) match the given type(s) according to the chosen logic, otherwise `false`.
1303
1303
  */
1304
1304
 
@@ -1337,20 +1337,9 @@ export function instancesof(
1337
1337
 
1338
1338
  // ================================================================
1339
1339
 
1340
- if (len === 3)
1341
- if (checkType(arguments[2], boolean) || arguments[2] instanceof Boolean)
1342
- return isinstancesof(objs, type, and, logic_or_match, strict);
1343
-
1344
- if (len === 4) {
1345
- if (
1346
- not(checkType(arguments[3], boolean)) &&
1347
- not(arguments[3] instanceof Boolean)
1348
- )
1349
- throw new TypeError("forth argument must be true or false");
1350
-
1351
- if (checkType(arguments[2], boolean) || arguments[2] instanceof Boolean)
1340
+ if (len > 2 && len < 5)
1341
+ if (checkType(logic_or_match, boolean) || logic_or_match instanceof Boolean)
1352
1342
  return isinstancesof(objs, type, and, logic_or_match, match_or_strict);
1353
- }
1354
1343
 
1355
1344
  return isinstancesof(objs, type, logic_or_match, match_or_strict, strict);
1356
1345
  }
@@ -1384,9 +1373,9 @@ export function isinstance(obj, cls) {
1384
1373
  * @template T - The instance type returned by the constructor(s).
1385
1374
  * @param {*|Array<*>} objs - The object or array of objects to test.
1386
1375
  * @param {(new (...args: any[]) => T) | Array<new (...args: any[]) => T>} type - The constructor or list of constructors to test against.
1387
- * @param {"and" | "or" | boolean} logic_or_match - Logic mode: `"and"` requires all matches, `"or"` allows any match.
1388
- * @param {boolean} match_or_strict - Whether to compare classes names strictly or loosely.
1389
- * @param {boolean} strict - If `true`, enables strict comparison behavior.
1376
+ * @param {("and" | "or") | String | (boolean | Boolean)} logic_or_match - Logic mode: `"and"` requires all matches, `"or"` allows any match.
1377
+ * @param {boolean | Boolean} match_or_strict - Whether to compare classes names strictly or loosely.
1378
+ * @param {boolean | Boolean} strict - If `true`, enables strict comparison behavior.
1390
1379
  * @returns {boolean} `true` if the provided object(s) match the given type(s) according to the chosen logic, otherwise `false`.
1391
1380
  */
1392
1381
 
@@ -1409,9 +1398,9 @@ export function isinstances(
1409
1398
  *
1410
1399
  * @param {* | Array<*>} data - The value or array of values to check.
1411
1400
  * @param {* | Array<*>} dataType - The expected type or array of expected types.
1412
- * @param {"and" | "or" | boolean} logic_or_match - Logic mode: `"and"` requires all matches, `"or"` allows any match.
1413
- * @param {boolean} match_or_strict - Whether to compare type names strictly or loosely.
1414
- * @param {boolean} strict - If `true`, enforces strict comparison rules.
1401
+ * @param {("and" | "or") | String | (boolean | Boolean)} logic_or_match - Logic mode: `"and"` requires all matches, `"or"` allows any match.
1402
+ * @param {boolean | Boolean} match_or_strict - Whether to compare type names strictly or loosely.
1403
+ * @param {boolean | Boolean} strict - If `true`, enforces strict comparison rules.
1415
1404
  * @returns {boolean} `true` if the data matches the expected type(s) according to the given logic, otherwise `false`.
1416
1405
  */
1417
1406
 
@@ -1450,20 +1439,9 @@ export function isType(
1450
1439
 
1451
1440
  // ================================================================
1452
1441
 
1453
- if (len === 3)
1454
- if (checkType(arguments[2], boolean) || arguments[2] instanceof Boolean)
1455
- return checkType(data, dataType, and, logic_or_match, strict);
1456
-
1457
- if (len === 4) {
1458
- if (
1459
- not(checkType(arguments[3], boolean)) &&
1460
- not(arguments[3] instanceof Boolean)
1461
- )
1462
- throw new TypeError("forth argument must be true or false");
1463
-
1464
- if (checkType(arguments[2], boolean) || arguments[2] instanceof Boolean)
1442
+ if (len > 2 && len < 5)
1443
+ if (checkType(logic_or_match, boolean) || logic_or_match instanceof Boolean)
1465
1444
  return checkType(data, dataType, and, logic_or_match, match_or_strict);
1466
- }
1467
1445
 
1468
1446
  return checkType(data, dataType, logic_or_match, match_or_strict, strict);
1469
1447
  }
@@ -1570,10 +1548,14 @@ export function log(...data) {
1570
1548
  */
1571
1549
 
1572
1550
  export function not(obj) {
1573
- if (arguments.length === 0)
1574
- throw new TypeError("not() takes exactly one argument (0 given)");
1551
+ /** @type {number} */
1552
+
1553
+ let len = arguments.length;
1554
+
1555
+ if (len !== 1)
1556
+ throw new TypeError(`not() takes exactly one argument (${len} given)`);
1575
1557
 
1576
- if (obj instanceof Boolean) return obj == false;
1558
+ if (obj instanceof Boolean) return obj.valueOf() === false;
1577
1559
 
1578
1560
  return obj?.length === 0 || !obj; // handling the object case
1579
1561
  }
@@ -1628,6 +1610,89 @@ export function puts(...data) {
1628
1610
  console.log(...data);
1629
1611
  }
1630
1612
 
1613
+ /**
1614
+ * Validates function arguments strictly at runtime.
1615
+ *
1616
+ * Ensures that:
1617
+ * 1. `useStrict` is called with exactly three arguments:
1618
+ * - `func`: the function to validate against
1619
+ * - `args`: an array or array-like object of arguments intended for `func`
1620
+ * - `optional`: optional arguments number in the function
1621
+ * 2. `func` is a function.
1622
+ * 3. `args` is array-like.
1623
+ * 4. `optional` is a number.
1624
+ * 5. The number of elements in `args` greater than or equal the number of parameters `func` expects.
1625
+ * 6. The number of elements in `args` less than or equal the number of parameters `func` + `optional` expects.
1626
+ *
1627
+ * @param {Function} func - The function whose arguments are being validated.
1628
+ * @param {Array|IArguments} args - The array-like object of arguments to check against the function's parameter count.
1629
+ * @param {number | Number} optional - default arguments number in the function.
1630
+ * @param {boolean | Boolean} postArgs - extra argument(s) after positional and optional ones `...args: any[]`.
1631
+ * @throws {TypeError} If called with a number of arguments less than 2.
1632
+ * @throws {TypeError} If called with a number of arguments greater than 3.
1633
+ * @throws {TypeError} If `func` is not a function.
1634
+ * @throws {TypeError} If `args` is not array-like.
1635
+ * @throws {TypeError} If `optional` is a negative number or not a number at all.
1636
+ * @throws {TypeError} If the length of `args` is less than the parameters number of `func`.
1637
+ * @throws {TypeError} If the length of `args` is greater than the parameters number of `func` + `optional`.
1638
+ * @returns {void} This function does not return a value.
1639
+ */
1640
+
1641
+ function strict(func, args, optional, postArgs) {
1642
+ if (!(func instanceof Function))
1643
+ throw new TypeError("first argument must be a function");
1644
+
1645
+ if (typeof args !== "object" || typeof args.length !== "number")
1646
+ throw new TypeError("second argument must be array-like");
1647
+
1648
+ if (
1649
+ (typeof optional !== "number" && !(optional instanceof Number)) ||
1650
+ optional < 0
1651
+ )
1652
+ throw new TypeError("third argument must be a positive number");
1653
+
1654
+ /** @type {string} */
1655
+
1656
+ const funcName = func.name;
1657
+
1658
+ /** @type {number} */
1659
+
1660
+ const paramsNumber = func.length;
1661
+
1662
+ /** @type {number} */
1663
+
1664
+ const argsNumber = args.length;
1665
+
1666
+ if (argsNumber < paramsNumber)
1667
+ throw new TypeError(
1668
+ `${funcName}() takes ${paramsNumber} positional argument(s) but ${argsNumber} were given`
1669
+ );
1670
+
1671
+ if (not(postArgs))
1672
+ if (argsNumber > paramsNumber + optional) {
1673
+ if (paramsNumber > 0 && optional > 0)
1674
+ throw new TypeError(
1675
+ `${funcName}() takes ${
1676
+ paramsNumber + optional
1677
+ } arguments in total but ${argsNumber} were given`
1678
+ );
1679
+
1680
+ if (paramsNumber > 0)
1681
+ throw new TypeError(
1682
+ `${funcName}() takes ${paramsNumber} positional argument(s) in total but ${argsNumber} were given`
1683
+ );
1684
+
1685
+ if (optional > 0)
1686
+ throw new TypeError(
1687
+ `${funcName}() takes ${optional} optional argument(s) in total but ${argsNumber} were given`
1688
+ );
1689
+
1690
+ throw new TypeError(
1691
+ `${funcName}() takes no argument(s) but ${argsNumber} were given`
1692
+ );
1693
+ }
1694
+ }
1695
+
1631
1696
  /**
1632
1697
  * Returns the JavaScript type of a value using the `typeof` operator.
1633
1698
  *
@@ -1708,31 +1773,19 @@ export function typesof(...objs) {
1708
1773
  /**
1709
1774
  * Validates function arguments strictly at runtime.
1710
1775
  *
1711
- * Ensures that:
1712
- * 1. `useStrict` is called with exactly three arguments:
1713
- * - `func`: the function to validate against
1714
- * - `args`: an array or array-like object of arguments intended for `func`
1715
- * - `optional`: optional arguments number in the function
1716
- * 2. `func` is a function.
1717
- * 3. `args` is array-like.
1718
- * 4. `optional` is a number.
1719
- * 5. The number of elements in `args` greater than or equal the number of parameters `func` expects.
1720
- * 6. The number of elements in `args` less than or equal the number of parameters `func` + `optional` expects.
1721
- *
1722
1776
  * @param {Function} func - The function whose arguments are being validated.
1723
1777
  * @param {Array|IArguments} args - The array-like object of arguments to check against the function's parameter count.
1724
- * @param {number} optional - default arguments number in the function.
1725
- * @throws {TypeError} If called with a number of arguments less than 2.
1726
- * @throws {TypeError} If called with a number of arguments greater than 3.
1727
- * @throws {TypeError} If `func` is not a function.
1728
- * @throws {TypeError} If `args` is not array-like.
1729
- * @throws {TypeError} If `optional` is a negative number or not a number at all.
1730
- * @throws {TypeError} If the length of `args` is less than the parameters number of `func`.
1731
- * @throws {TypeError} If the length of `args` is greater than the parameters number of `func` + `optional`.
1778
+ * @param {number | Number} optional_or_postArgs - default arguments number in the function.
1779
+ * @param {boolean | Boolean} postArgs - extra argument(s) after positional and optional ones `...args: any[]`.
1732
1780
  * @returns {void} This function does not return a value.
1733
1781
  */
1734
1782
 
1735
- export function useStrict(func, args, optional = 0) {
1783
+ export function useStrict(
1784
+ func,
1785
+ args,
1786
+ optional_or_postArgs = 0,
1787
+ postArgs = false
1788
+ ) {
1736
1789
  /** @type {number} */
1737
1790
 
1738
1791
  const len = arguments.length;
@@ -1744,59 +1797,22 @@ export function useStrict(func, args, optional = 0) {
1744
1797
  : "useStrict() missing 2 required arguments: 'func' and 'args'"
1745
1798
  );
1746
1799
 
1747
- if (len > 3)
1748
- throw TypeError(
1749
- `useStrict() takes 3 arguments in total but ${len} were given`
1750
- );
1751
-
1752
- if (!(func instanceof Function))
1753
- throw TypeError("first argument must be a function");
1754
-
1755
- if (typeof args !== "object" || typeof args.length !== "number")
1756
- throw TypeError("second argument must be array-like");
1757
-
1758
- if (typeof optional !== "number" || optional < 0)
1759
- throw TypeError("third argument must be a positive number");
1760
-
1761
- /** @type {string} */
1762
-
1763
- const funcName = func.name;
1764
-
1765
- /** @type {number} */
1766
-
1767
- const paramsNumber = func.length;
1768
-
1769
- /** @type {number} */
1770
-
1771
- const argsNumber = args.length;
1772
-
1773
- if (argsNumber < paramsNumber)
1774
- throw TypeError(
1775
- `${funcName}() takes ${paramsNumber} positional argument(s) but ${argsNumber} were given`
1800
+ if (len > 4)
1801
+ throw new TypeError(
1802
+ `useStrict() takes 4 arguments in total but ${len} were given`
1776
1803
  );
1777
1804
 
1778
- if (argsNumber > paramsNumber + optional) {
1779
- if (paramsNumber > 0 && optional > 0)
1780
- throw TypeError(
1781
- `${funcName}() takes ${
1782
- paramsNumber + optional
1783
- } arguments in total but ${argsNumber} were given`
1784
- );
1785
-
1786
- if (paramsNumber > 0)
1787
- throw TypeError(
1788
- `${funcName}() takes ${paramsNumber} positional argument(s) in total but ${argsNumber} were given`
1789
- );
1790
-
1791
- if (optional > 0)
1792
- throw TypeError(
1793
- `${funcName}() takes ${optional} optional argument(s) in total but ${argsNumber} were given`
1794
- );
1805
+ if (len === 3) {
1806
+ if (
1807
+ typeof optional_or_postArgs === "boolean" ||
1808
+ optional_or_postArgs instanceof Boolean
1809
+ )
1810
+ strict(func, args, 0, optional_or_postArgs);
1795
1811
 
1796
- throw TypeError(
1797
- `${funcName}() takes no argument(s) but ${argsNumber} were given`
1798
- );
1812
+ return;
1799
1813
  }
1814
+
1815
+ strict(func, args, optional_or_postArgs, postArgs);
1800
1816
  }
1801
1817
 
1802
1818
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsfunx",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "description": "JavaScript utility functions for cleaner, more readable code",
5
5
  "main": "./jsfunx.cjs",
6
6
  "module": "./jsfunx.mjs",