@20syldev/api 4.6.0 → 4.8.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 (111) hide show
  1. package/README.md +5 -3
  2. package/dist/app.js +6 -6
  3. package/dist/app.js.map +1 -1
  4. package/dist/config/env.js.map +1 -1
  5. package/dist/config/versions.js +22 -3
  6. package/dist/config/versions.js.map +1 -1
  7. package/dist/constants.js +27 -12
  8. package/dist/constants.js.map +1 -1
  9. package/dist/middleware/error.js +2 -2
  10. package/dist/middleware/error.js.map +1 -1
  11. package/dist/middleware/logger.js.map +1 -1
  12. package/dist/middleware/ratelimit.js +2 -2
  13. package/dist/middleware/ratelimit.js.map +1 -1
  14. package/dist/middleware/version.js.map +1 -1
  15. package/dist/modules/v3.js +1 -1
  16. package/dist/modules/v3.js.map +1 -1
  17. package/dist/modules/v4/address.js +381 -0
  18. package/dist/modules/v4/address.js.map +1 -0
  19. package/dist/modules/v4/agent.js +92 -0
  20. package/dist/modules/v4/agent.js.map +1 -0
  21. package/dist/modules/v4/algorithms.js +79 -0
  22. package/dist/modules/v4/algorithms.js.map +1 -1
  23. package/dist/modules/v4/avatar.js +136 -0
  24. package/dist/modules/v4/avatar.js.map +1 -0
  25. package/dist/modules/v4/barcode.js +440 -0
  26. package/dist/modules/v4/barcode.js.map +1 -0
  27. package/dist/modules/v4/captcha.js +7 -0
  28. package/dist/modules/v4/captcha.js.map +1 -1
  29. package/dist/modules/v4/chat.js +9 -1
  30. package/dist/modules/v4/chat.js.map +1 -1
  31. package/dist/modules/v4/color.js +8 -1
  32. package/dist/modules/v4/color.js.map +1 -1
  33. package/dist/modules/v4/convert.js +9 -0
  34. package/dist/modules/v4/convert.js.map +1 -1
  35. package/dist/modules/v4/credit.js +104 -0
  36. package/dist/modules/v4/credit.js.map +1 -0
  37. package/dist/modules/v4/cron.js +202 -0
  38. package/dist/modules/v4/cron.js.map +1 -0
  39. package/dist/modules/v4/dice.js +7 -0
  40. package/dist/modules/v4/dice.js.map +1 -1
  41. package/dist/modules/v4/domain.js +6 -1
  42. package/dist/modules/v4/domain.js.map +1 -1
  43. package/dist/modules/v4/encode.js +71 -0
  44. package/dist/modules/v4/encode.js.map +1 -1
  45. package/dist/modules/v4/geo.js +11 -1
  46. package/dist/modules/v4/geo.js.map +1 -1
  47. package/dist/modules/v4/hash.js +10 -1
  48. package/dist/modules/v4/hash.js.map +1 -1
  49. package/dist/modules/v4/hyperplanning.js +9 -1
  50. package/dist/modules/v4/hyperplanning.js.map +1 -1
  51. package/dist/modules/v4/ip.js +132 -0
  52. package/dist/modules/v4/ip.js.map +1 -0
  53. package/dist/modules/v4/levenshtein.js +8 -0
  54. package/dist/modules/v4/levenshtein.js.map +1 -1
  55. package/dist/modules/v4/palette.js +9 -1
  56. package/dist/modules/v4/palette.js.map +1 -1
  57. package/dist/modules/v4/password.js +343 -0
  58. package/dist/modules/v4/password.js.map +1 -0
  59. package/dist/modules/v4/personal.js +14 -18
  60. package/dist/modules/v4/personal.js.map +1 -1
  61. package/dist/modules/v4/placeholder.js +8 -0
  62. package/dist/modules/v4/placeholder.js.map +1 -1
  63. package/dist/modules/v4/qrcode.js +10 -3
  64. package/dist/modules/v4/qrcode.js.map +1 -1
  65. package/dist/modules/v4/regex.js +48 -0
  66. package/dist/modules/v4/regex.js.map +1 -0
  67. package/dist/modules/v4/statistics.js +7 -0
  68. package/dist/modules/v4/statistics.js.map +1 -1
  69. package/dist/modules/v4/text.js +30 -0
  70. package/dist/modules/v4/text.js.map +1 -1
  71. package/dist/modules/v4/tic_tac_toe.js +9 -1
  72. package/dist/modules/v4/tic_tac_toe.js.map +1 -1
  73. package/dist/modules/v4/time.js +62 -11
  74. package/dist/modules/v4/time.js.map +1 -1
  75. package/dist/modules/v4/token.js +17 -8
  76. package/dist/modules/v4/token.js.map +1 -1
  77. package/dist/modules/v4/username.js +5 -0
  78. package/dist/modules/v4/username.js.map +1 -1
  79. package/dist/modules/v4/validate.js +21 -0
  80. package/dist/modules/v4/validate.js.map +1 -1
  81. package/dist/modules/v4.js +10 -1
  82. package/dist/modules/v4.js.map +1 -1
  83. package/dist/routes/delete.js.map +1 -1
  84. package/dist/routes/get.js +208 -48
  85. package/dist/routes/get.js.map +1 -1
  86. package/dist/routes/index.js +2 -2
  87. package/dist/routes/index.js.map +1 -1
  88. package/dist/routes/patch.js.map +1 -1
  89. package/dist/routes/post.js +2 -2
  90. package/dist/routes/post.js.map +1 -1
  91. package/dist/utils/response.js.map +1 -1
  92. package/package.json +1 -1
  93. package/src/config/versions.ts +8 -1
  94. package/src/constants.ts +27 -12
  95. package/src/modules/v4/address.ts +412 -0
  96. package/src/modules/v4/cron.ts +221 -0
  97. package/src/modules/v4/geo.ts +2 -1
  98. package/src/modules/v4/password.ts +379 -0
  99. package/src/modules/v4/personal.ts +4 -16
  100. package/src/modules/v4/qrcode.ts +2 -2
  101. package/src/modules/v4/regex.ts +67 -0
  102. package/src/modules/v4/time.ts +63 -17
  103. package/src/modules/v4/token.ts +8 -7
  104. package/src/modules/v4.ts +4 -0
  105. package/src/routes/get.ts +125 -46
  106. package/tests/integration/api.test.ts +111 -0
  107. package/tests/unit/address.test.ts +84 -0
  108. package/tests/unit/cron.test.ts +110 -0
  109. package/tests/unit/password.test.ts +86 -0
  110. package/tests/unit/regex.test.ts +95 -0
  111. package/tests/unit/time.test.ts +47 -0
@@ -0,0 +1,95 @@
1
+ import { strict as assert } from 'node:assert';
2
+ import { describe, test } from 'node:test';
3
+
4
+ import regex from '../../src/modules/v4/regex.js';
5
+
6
+ describe('regex', () => {
7
+ describe('basic matching', () => {
8
+ test('finds a simple match', () => {
9
+ const r = regex('hello', 'hello world');
10
+ assert.equal(r.valid, true);
11
+ assert.equal(r.count, 1);
12
+ assert.equal(r.matches[0]!.match, 'hello');
13
+ assert.equal(r.matches[0]!.index, 0);
14
+ });
15
+
16
+ test('finds multiple matches', () => {
17
+ const r = regex('\\d+', 'abc 42 def 7');
18
+ assert.equal(r.count, 2);
19
+ assert.equal(r.matches[0]!.match, '42');
20
+ assert.equal(r.matches[1]!.match, '7');
21
+ });
22
+
23
+ test('no match returns empty array', () => {
24
+ const r = regex('xyz', 'hello world');
25
+ assert.equal(r.valid, true);
26
+ assert.equal(r.count, 0);
27
+ assert.deepEqual(r.matches, []);
28
+ });
29
+ });
30
+
31
+ describe('flags', () => {
32
+ test('flag i enables case-insensitive matching', () => {
33
+ const r = regex('hello', 'HELLO world', 'i');
34
+ assert.equal(r.count, 1);
35
+ assert.equal(r.matches[0]!.match, 'HELLO');
36
+ });
37
+
38
+ test('invalid flag x is silently ignored', () => {
39
+ const r = regex('hello', 'hello world', 'x');
40
+ assert.equal(r.valid, true);
41
+ assert.equal(r.count, 1);
42
+ });
43
+
44
+ test('g flag is always present', () => {
45
+ const r = regex('a', 'aaa', '');
46
+ assert.ok(r.flags.includes('g'));
47
+ });
48
+ });
49
+
50
+ describe('capture groups', () => {
51
+ test('numbered groups are returned', () => {
52
+ const r = regex('(\\d{4})-(\\d{2})', '2026-05');
53
+ assert.deepEqual(r.matches[0]!.groups, ['2026', '05']);
54
+ });
55
+
56
+ test('named groups are returned', () => {
57
+ const r = regex('(?<year>\\d{4})-(?<month>\\d{2})', '2026-05');
58
+ assert.equal(r.matches[0]!.namedGroups.year, '2026');
59
+ assert.equal(r.matches[0]!.namedGroups.month, '05');
60
+ });
61
+
62
+ test('no groups returns empty arrays', () => {
63
+ const r = regex('hello', 'hello');
64
+ assert.deepEqual(r.matches[0]!.groups, []);
65
+ assert.deepEqual(r.matches[0]!.namedGroups, {});
66
+ });
67
+ });
68
+
69
+ describe('invalid pattern', () => {
70
+ test('invalid regex returns valid: false', () => {
71
+ const r = regex('[invalid', 'hello');
72
+ assert.equal(r.valid, false);
73
+ assert.equal(r.count, 0);
74
+ assert.deepEqual(r.matches, []);
75
+ });
76
+ });
77
+
78
+ describe('errors', () => {
79
+ test('missing pattern throws', () => {
80
+ assert.throws(() => regex('', 'hello'), /pattern/);
81
+ });
82
+
83
+ test('missing text throws', () => {
84
+ assert.throws(() => regex('hello', ''), /text/);
85
+ });
86
+
87
+ test('pattern too long throws', () => {
88
+ assert.throws(() => regex('a'.repeat(201), 'hello'), /200/);
89
+ });
90
+
91
+ test('text too long throws', () => {
92
+ assert.throws(() => regex('hello', 'a'.repeat(1001)), /1000/);
93
+ });
94
+ });
95
+ });
@@ -65,4 +65,51 @@ describe('time', () => {
65
65
  const result = time('live', undefined, undefined, undefined, 'Europe/Paris');
66
66
  assert.equal(result.timezone, 'Europe/Paris');
67
67
  });
68
+
69
+ describe('countdown', () => {
70
+ test('future date returns direction future', () => {
71
+ const future = new Date(Date.now() + 7 * 24 * 3600 * 1000).toISOString();
72
+ const r = time('countdown', undefined, undefined, undefined, undefined, future);
73
+ assert.equal(r.direction, 'future');
74
+ });
75
+
76
+ test('past date returns direction past', () => {
77
+ const past = new Date(Date.now() - 7 * 24 * 3600 * 1000).toISOString();
78
+ const r = time('countdown', undefined, undefined, undefined, undefined, past);
79
+ assert.equal(r.direction, 'past');
80
+ });
81
+
82
+ test('remaining breakdown is correct', () => {
83
+ const target = new Date(Date.now() + 2 * 86400 * 1000 + 3 * 3600 * 1000).toISOString();
84
+ const r = time('countdown', undefined, undefined, undefined, undefined, target);
85
+ const rem = r.remaining as { days: number; hours: number };
86
+ assert.equal(rem.days, 2);
87
+ assert.equal(rem.hours, 3);
88
+ });
89
+
90
+ test('human skips zero units', () => {
91
+ const target = new Date(Date.now() + 3 * 86400 * 1000).toISOString();
92
+ const r = time('countdown', undefined, undefined, undefined, undefined, target);
93
+ assert.ok(!(r.human as string).includes('hour'));
94
+ assert.ok(!(r.human as string).includes('minute'));
95
+ });
96
+
97
+ test('throws on missing target', () => {
98
+ assert.throws(() => time('countdown'), /target date/);
99
+ });
100
+
101
+ test('throws on invalid target', () => {
102
+ assert.throws(
103
+ () => time('countdown', undefined, undefined, undefined, undefined, 'not-a-date'),
104
+ /valid target date/,
105
+ );
106
+ });
107
+
108
+ test('throws if target is more than 100 years away', () => {
109
+ assert.throws(
110
+ () => time('countdown', undefined, undefined, undefined, undefined, '2200-01-01'),
111
+ /100 years/,
112
+ );
113
+ });
114
+ });
68
115
  });