@20syldev/api 3.5.0 → 4.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.
Files changed (213) hide show
  1. package/.prettierrc +7 -0
  2. package/README.md +32 -33
  3. package/dist/app.js +36 -0
  4. package/dist/app.js.map +1 -0
  5. package/dist/config/env.js +73 -0
  6. package/dist/config/env.js.map +1 -0
  7. package/dist/config/versions.js +72 -0
  8. package/dist/config/versions.js.map +1 -0
  9. package/dist/constants.js +42 -0
  10. package/dist/constants.js.map +1 -0
  11. package/dist/middleware/cors.js +15 -0
  12. package/dist/middleware/cors.js.map +1 -0
  13. package/dist/middleware/error.js +6 -0
  14. package/dist/middleware/error.js.map +1 -0
  15. package/dist/middleware/json.js +8 -0
  16. package/dist/middleware/json.js.map +1 -0
  17. package/dist/middleware/logger.js +26 -0
  18. package/dist/middleware/logger.js.map +1 -0
  19. package/dist/middleware/ratelimit.js +58 -0
  20. package/dist/middleware/ratelimit.js.map +1 -0
  21. package/dist/middleware/version.js +30 -0
  22. package/dist/middleware/version.js.map +1 -0
  23. package/dist/modules/v3/algorithms.js +221 -0
  24. package/dist/modules/v3/algorithms.js.map +1 -0
  25. package/{modules → dist/modules}/v3/captcha.js +4 -13
  26. package/dist/modules/v3/captcha.js.map +1 -0
  27. package/dist/modules/v3/chat.js +103 -0
  28. package/dist/modules/v3/chat.js.map +1 -0
  29. package/{modules → dist/modules}/v3/color.js +12 -13
  30. package/dist/modules/v3/color.js.map +1 -0
  31. package/dist/modules/v3/convert.js +41 -0
  32. package/dist/modules/v3/convert.js.map +1 -0
  33. package/dist/modules/v3/domain.js +83 -0
  34. package/dist/modules/v3/domain.js.map +1 -0
  35. package/dist/modules/v3/hash.js +16 -0
  36. package/dist/modules/v3/hash.js.map +1 -0
  37. package/dist/modules/v3/hyperplanning.js +50 -0
  38. package/dist/modules/v3/hyperplanning.js.map +1 -0
  39. package/dist/modules/v3/levenshtein.js +38 -0
  40. package/dist/modules/v3/levenshtein.js.map +1 -0
  41. package/dist/modules/v3/personal.js +129 -0
  42. package/dist/modules/v3/personal.js.map +1 -0
  43. package/dist/modules/v3/qrcode.js +21 -0
  44. package/dist/modules/v3/qrcode.js.map +1 -0
  45. package/dist/modules/v3/tic_tac_toe.js +221 -0
  46. package/dist/modules/v3/tic_tac_toe.js.map +1 -0
  47. package/dist/modules/v3/time.js +88 -0
  48. package/dist/modules/v3/time.js.map +1 -0
  49. package/{modules → dist/modules}/v3/token.js +10 -11
  50. package/dist/modules/v3/token.js.map +1 -0
  51. package/dist/modules/v3/username.js +92 -0
  52. package/dist/modules/v3/username.js.map +1 -0
  53. package/dist/modules/v3/utils.js +70 -0
  54. package/dist/modules/v3/utils.js.map +1 -0
  55. package/dist/modules/v3.js +16 -0
  56. package/dist/modules/v3.js.map +1 -0
  57. package/dist/modules/v4/algorithms.js +200 -0
  58. package/dist/modules/v4/algorithms.js.map +1 -0
  59. package/dist/modules/v4/captcha.js +35 -0
  60. package/dist/modules/v4/captcha.js.map +1 -0
  61. package/dist/modules/v4/chat.js +92 -0
  62. package/dist/modules/v4/chat.js.map +1 -0
  63. package/dist/modules/v4/color.js +43 -0
  64. package/dist/modules/v4/color.js.map +1 -0
  65. package/dist/modules/v4/convert.js +33 -0
  66. package/dist/modules/v4/convert.js.map +1 -0
  67. package/dist/modules/v4/dice.js +30 -0
  68. package/dist/modules/v4/dice.js.map +1 -0
  69. package/dist/modules/v4/domain.js +78 -0
  70. package/dist/modules/v4/domain.js.map +1 -0
  71. package/dist/modules/v4/encode.js +165 -0
  72. package/dist/modules/v4/encode.js.map +1 -0
  73. package/dist/modules/v4/geo.js +41 -0
  74. package/dist/modules/v4/geo.js.map +1 -0
  75. package/dist/modules/v4/hash.js +9 -0
  76. package/dist/modules/v4/hash.js.map +1 -0
  77. package/dist/modules/v4/hyperplanning.js +42 -0
  78. package/dist/modules/v4/hyperplanning.js.map +1 -0
  79. package/dist/modules/v4/levenshtein.js +29 -0
  80. package/dist/modules/v4/levenshtein.js.map +1 -0
  81. package/dist/modules/v4/palette.js +89 -0
  82. package/dist/modules/v4/palette.js.map +1 -0
  83. package/dist/modules/v4/personal.js +125 -0
  84. package/dist/modules/v4/personal.js.map +1 -0
  85. package/dist/modules/v4/placeholder.js +96 -0
  86. package/dist/modules/v4/placeholder.js.map +1 -0
  87. package/dist/modules/v4/qrcode.js +12 -0
  88. package/dist/modules/v4/qrcode.js.map +1 -0
  89. package/dist/modules/v4/statistics.js +41 -0
  90. package/dist/modules/v4/statistics.js.map +1 -0
  91. package/dist/modules/v4/text.js +293 -0
  92. package/dist/modules/v4/text.js.map +1 -0
  93. package/dist/modules/v4/tic_tac_toe.js +206 -0
  94. package/dist/modules/v4/tic_tac_toe.js.map +1 -0
  95. package/dist/modules/v4/time.js +73 -0
  96. package/dist/modules/v4/time.js.map +1 -0
  97. package/dist/modules/v4/token.js +36 -0
  98. package/dist/modules/v4/token.js.map +1 -0
  99. package/dist/modules/v4/username.js +87 -0
  100. package/dist/modules/v4/username.js.map +1 -0
  101. package/dist/modules/v4/utils.js +26 -0
  102. package/dist/modules/v4/utils.js.map +1 -0
  103. package/dist/modules/v4/validate.js +54 -0
  104. package/dist/modules/v4/validate.js.map +1 -0
  105. package/dist/modules/v4.js +18 -0
  106. package/dist/modules/v4.js.map +1 -0
  107. package/dist/routes/delete.js +65 -0
  108. package/dist/routes/delete.js.map +1 -0
  109. package/dist/routes/get.js +441 -0
  110. package/dist/routes/get.js.map +1 -0
  111. package/dist/routes/index.js +50 -0
  112. package/dist/routes/index.js.map +1 -0
  113. package/dist/routes/patch.js +41 -0
  114. package/dist/routes/patch.js.map +1 -0
  115. package/dist/routes/post.js +185 -0
  116. package/dist/routes/post.js.map +1 -0
  117. package/dist/storage/index.js +13 -0
  118. package/dist/storage/index.js.map +1 -0
  119. package/dist/types/storage.js +2 -0
  120. package/dist/types/storage.js.map +1 -0
  121. package/dist/utils/response.js +10 -0
  122. package/dist/utils/response.js.map +1 -0
  123. package/dist/utils/version.js +3 -0
  124. package/dist/utils/version.js.map +1 -0
  125. package/docs/changelog.md +333 -0
  126. package/eslint.config.js +20 -0
  127. package/package.json +31 -15
  128. package/src/app.ts +48 -0
  129. package/src/config/env.ts +81 -0
  130. package/src/config/versions.ts +92 -0
  131. package/src/constants.ts +47 -0
  132. package/src/middleware/cors.ts +17 -0
  133. package/src/middleware/error.ts +7 -0
  134. package/src/middleware/json.ts +9 -0
  135. package/src/middleware/logger.ts +31 -0
  136. package/src/middleware/ratelimit.ts +66 -0
  137. package/src/middleware/version.ts +39 -0
  138. package/{modules → src/modules}/v3/algorithms.js +1 -1
  139. package/src/modules/v3/captcha.js +60 -0
  140. package/{modules → src/modules}/v3/chat.js +6 -4
  141. package/src/modules/v3/color.js +60 -0
  142. package/{modules → src/modules}/v3/convert.js +5 -5
  143. package/{modules → src/modules}/v3/domain.js +51 -4
  144. package/{modules → src/modules}/v3/hash.js +1 -1
  145. package/{modules → src/modules}/v3/hyperplanning.js +11 -10
  146. package/{modules → src/modules}/v3/levenshtein.js +3 -3
  147. package/{modules → src/modules}/v3/personal.js +20 -8
  148. package/{modules → src/modules}/v3/qrcode.js +1 -1
  149. package/{modules → src/modules}/v3/tic_tac_toe.js +24 -18
  150. package/{modules → src/modules}/v3/time.js +22 -11
  151. package/src/modules/v3/token.js +54 -0
  152. package/src/modules/v3/username.js +94 -0
  153. package/{modules → src/modules}/v3/utils.js +2 -2
  154. package/{modules → src/modules}/v3.js +1 -1
  155. package/src/modules/v4/algorithms.ts +197 -0
  156. package/src/modules/v4/captcha.ts +49 -0
  157. package/src/modules/v4/chat.ts +122 -0
  158. package/src/modules/v4/color.ts +64 -0
  159. package/src/modules/v4/convert.ts +38 -0
  160. package/src/modules/v4/dice.ts +39 -0
  161. package/src/modules/v4/domain.ts +81 -0
  162. package/src/modules/v4/encode.ts +170 -0
  163. package/src/modules/v4/geo.ts +53 -0
  164. package/src/modules/v4/hash.ts +9 -0
  165. package/src/modules/v4/hyperplanning.ts +58 -0
  166. package/src/modules/v4/levenshtein.ts +38 -0
  167. package/src/modules/v4/palette.ts +103 -0
  168. package/src/modules/v4/personal.ts +147 -0
  169. package/src/modules/v4/placeholder.ts +122 -0
  170. package/src/modules/v4/qrcode.ts +11 -0
  171. package/src/modules/v4/statistics.ts +55 -0
  172. package/src/modules/v4/text.ts +300 -0
  173. package/src/modules/v4/tic_tac_toe.ts +255 -0
  174. package/src/modules/v4/time.ts +92 -0
  175. package/src/modules/v4/token.ts +43 -0
  176. package/src/modules/v4/username.ts +89 -0
  177. package/src/modules/v4/utils.ts +38 -0
  178. package/src/modules/v4/validate.ts +55 -0
  179. package/src/modules/v4.ts +17 -0
  180. package/src/routes/delete.ts +72 -0
  181. package/src/routes/get.ts +508 -0
  182. package/src/routes/index.ts +58 -0
  183. package/src/routes/patch.ts +45 -0
  184. package/src/routes/post.ts +200 -0
  185. package/src/storage/index.ts +16 -0
  186. package/src/types/express.d.ts +17 -0
  187. package/src/types/storage.ts +48 -0
  188. package/src/utils/response.ts +11 -0
  189. package/src/utils/version.ts +5 -0
  190. package/tests/integration/api.test.ts +395 -0
  191. package/tests/tsconfig.json +3 -0
  192. package/tests/unit/algorithms.test.ts +120 -0
  193. package/tests/unit/color.test.ts +33 -0
  194. package/tests/unit/convert.test.ts +42 -0
  195. package/tests/unit/dice.test.ts +57 -0
  196. package/tests/unit/domain.test.ts +47 -0
  197. package/tests/unit/encode.test.ts +108 -0
  198. package/tests/unit/geo.test.ts +45 -0
  199. package/tests/unit/hash.test.ts +37 -0
  200. package/tests/unit/hyperplanning.test.ts +77 -0
  201. package/tests/unit/levenshtein.test.ts +34 -0
  202. package/tests/unit/palette.test.ts +53 -0
  203. package/tests/unit/personal.test.ts +65 -0
  204. package/tests/unit/statistics.test.ts +57 -0
  205. package/tests/unit/text.test.ts +107 -0
  206. package/tests/unit/time.test.ts +67 -0
  207. package/tests/unit/token.test.ts +61 -0
  208. package/tests/unit/username.test.ts +34 -0
  209. package/tests/unit/validate.test.ts +71 -0
  210. package/tsconfig.json +17 -0
  211. package/tsconfig.test.json +9 -0
  212. package/app.js +0 -865
  213. package/modules/v3/username.js +0 -32
@@ -6,9 +6,56 @@ import { random, genIP } from './utils.js';
6
6
  * @returns {Object} Domain details including DNS, hosting, and SEO metrics
7
7
  */
8
8
  export default function domain() {
9
- const subdomains = ['fr.', 'en.', 'docs.', 'api.', 'projects.', 'app.', 'web.', 'info.', 'dev.', 'shop.', 'blog.', 'support.', 'mail.', 'forum.'];
10
- const domains = ['example', 'site', 'test', 'demo', 'page', 'store', 'portfolio', 'platform', 'hub', 'network', 'service', 'cloud', 'solutions', 'company'];
11
- const tlds = ['.com', '.fr', '.eu', '.dev', '.net', '.org', '.io', '.tech', '.biz', '.info', '.co', '.app', '.store', '.online', '.shop', '.tv'];
9
+ const subdomains = [
10
+ 'fr.',
11
+ 'en.',
12
+ 'docs.',
13
+ 'api.',
14
+ 'projects.',
15
+ 'app.',
16
+ 'web.',
17
+ 'info.',
18
+ 'dev.',
19
+ 'shop.',
20
+ 'blog.',
21
+ 'support.',
22
+ 'mail.',
23
+ 'forum.',
24
+ ];
25
+ const domains = [
26
+ 'example',
27
+ 'site',
28
+ 'test',
29
+ 'demo',
30
+ 'page',
31
+ 'store',
32
+ 'portfolio',
33
+ 'platform',
34
+ 'hub',
35
+ 'network',
36
+ 'service',
37
+ 'cloud',
38
+ 'solutions',
39
+ 'company',
40
+ ];
41
+ const tlds = [
42
+ '.com',
43
+ '.fr',
44
+ '.eu',
45
+ '.dev',
46
+ '.net',
47
+ '.org',
48
+ '.io',
49
+ '.tech',
50
+ '.biz',
51
+ '.info',
52
+ '.co',
53
+ '.app',
54
+ '.store',
55
+ '.online',
56
+ '.shop',
57
+ '.tv',
58
+ ];
12
59
 
13
60
  const domain = `${random(domains)}${random(tlds)}`;
14
61
  const fulldomain = `${random(subdomains)}${domain}`;
@@ -36,4 +83,4 @@ export default function domain() {
36
83
  creation_date: new Date(Date.now() - Math.floor(Math.random() * 10000000000)).toISOString(),
37
84
  expiration_date: new Date(Date.now() + Math.floor(Math.random() * 10000000000)).toISOString(),
38
85
  };
39
- }
86
+ }
@@ -13,4 +13,4 @@ export default function hash(text, method) {
13
13
 
14
14
  const hash = createHash(method).update(text).digest('hex');
15
15
  return { method, hash };
16
- }
16
+ }
@@ -1,6 +1,5 @@
1
1
  import { formatDate } from './utils.js';
2
2
  import ical from 'ical.js';
3
- import fetch from 'node-fetch';
4
3
 
5
4
  /**
6
5
  * Parse an ICS calendar file and extract event information
@@ -19,24 +18,26 @@ export default async function hyperplanning(url, detail) {
19
18
 
20
19
  const events = new ical.Component(ical.parse(await response.text()))
21
20
  .getAllSubcomponents('vevent')
22
- .map(e => {
21
+ .map((e) => {
23
22
  const evt = new ical.Event(e);
24
- const summary = (evt.summary || '').split(' ').filter(part => part !== '-');
23
+ const summary = (evt.summary || '').split(' ').filter((part) => part !== '-');
25
24
  const start = formatDate(evt.startDate.toJSDate());
26
25
  const end = formatDate(evt.endDate.toJSDate());
27
26
 
28
27
  if (detail === 'full') {
29
- const desc = (evt.description || '').split('\n').map(l => l.trim());
30
- const extract = (p) => (desc.find(l => l.startsWith(p)) || '').replace(p, '').trim();
28
+ const desc = (evt.description || '').split('\n').map((l) => l.trim());
29
+ const extract = (p) => (desc.find((l) => l.startsWith(p)) || '').replace(p, '').trim();
31
30
 
32
31
  return {
33
32
  summary,
34
33
  subject: extract('Matière :'),
35
34
  teacher: extract('Enseignant :'),
36
- classes: extract('Promotions :').split(', ').map(c => c.trim()),
35
+ classes: extract('Promotions :')
36
+ .split(', ')
37
+ .map((c) => c.trim()),
37
38
  type: extract('Salle :') || undefined,
38
39
  start,
39
- end
40
+ end,
40
41
  };
41
42
  }
42
43
 
@@ -45,11 +46,11 @@ export default async function hyperplanning(url, detail) {
45
46
  return {
46
47
  summary: evt.summary || '',
47
48
  start,
48
- end
49
+ end,
49
50
  };
50
51
  })
51
52
  .sort((a, b) => new Date(a.start) - new Date(b.start))
52
- .filter(e => new Date(e.end) >= new Date());
53
+ .filter((e) => new Date(e.end) >= new Date());
53
54
 
54
55
  return events;
55
- }
56
+ }
@@ -33,7 +33,7 @@ export default function levenshtein(str1, str2) {
33
33
  m[i][j] = Math.min(
34
34
  m[i - 1][j] + 1,
35
35
  m[i][j - 1] + 1,
36
- m[i - 1][j - 1] + (str1[i - 1] !== str2[j - 1] ? 1 : 0)
36
+ m[i - 1][j - 1] + (str1[i - 1] !== str2[j - 1] ? 1 : 0),
37
37
  );
38
38
  }
39
39
  }
@@ -41,6 +41,6 @@ export default function levenshtein(str1, str2) {
41
41
  return {
42
42
  str1,
43
43
  str2,
44
- distance: m[str1.length][str2.length]
44
+ distance: m[str1.length][str2.length],
45
45
  };
46
- }
46
+ }
@@ -16,7 +16,7 @@ export default function personal() {
16
16
  { name: 'Daniel Brown', social: 'daniel_brown', email: 'daniel@example.com', country: 'JP' },
17
17
  { name: 'Sophia Wilson', social: 'sophia_wilson', email: 'sophia@example.com', country: 'BR' },
18
18
  { name: 'James Taylor', social: 'james_taylor', email: 'james@example.com', country: 'CA' },
19
- { name: 'Olivia Thomas', social: 'olivia_thomas', email: 'olivia@example.com', country: 'AU' }
19
+ { name: 'Olivia Thomas', social: 'olivia_thomas', email: 'olivia@example.com', country: 'AU' },
20
20
  ];
21
21
 
22
22
  const countries = {
@@ -29,12 +29,24 @@ export default function personal() {
29
29
  JP: { tel: '080-1234-5678', code: '81', lang: 'Japanese' },
30
30
  BR: { tel: '(11) 98765-4321', code: '55', lang: 'Portuguese' },
31
31
  CA: { tel: '416-123-4567', code: '1', lang: 'English' },
32
- AU: { tel: '0412 345 678', code: '61', lang: 'English' }
32
+ AU: { tel: '0412 345 678', code: '61', lang: 'English' },
33
33
  };
34
34
 
35
35
  const jobs = ['Writer', 'Artist', 'Musician', 'Explorer', 'Scientist', 'Engineer', 'Athlete', 'Doctor'];
36
36
  const hobbies = ['Reading', 'Traveling', 'Gaming', 'Cooking', 'Fitness', 'Music', 'Photography', 'Writing'];
37
- const cities = ['New York', 'Paris', 'London', 'Madrid', 'Berlin', 'Rome', 'Tokyo', 'Los Angeles', 'Sydney', 'São Paulo', 'Toronto'];
37
+ const cities = [
38
+ 'New York',
39
+ 'Paris',
40
+ 'London',
41
+ 'Madrid',
42
+ 'Berlin',
43
+ 'Rome',
44
+ 'Tokyo',
45
+ 'Los Angeles',
46
+ 'Sydney',
47
+ 'São Paulo',
48
+ 'Toronto',
49
+ ];
38
50
  const streets = ['Main St', '2nd Ave', 'Broadway', 'Park Lane', 'Elm St', 'Sunset Blvd', 'Maple St', 'Highland Rd'];
39
51
 
40
52
  const card = Array.from({ length: 4 }, () => randomNumber(1000, 9999)).join(' ');
@@ -66,7 +78,7 @@ export default function personal() {
66
78
  let emergencyContact = random(people);
67
79
  while (
68
80
  emergencyContact.email === person.email ||
69
- emergencyContacts.some(e => e.email === emergencyContact.email)
81
+ emergencyContacts.some((e) => e.email === emergencyContact.email)
70
82
  ) {
71
83
  emergencyContact = random(people);
72
84
  }
@@ -74,7 +86,7 @@ export default function personal() {
74
86
  emergencyContacts.push({
75
87
  name: emergencyContact.name,
76
88
  relationship: random(['Spouse', 'Parent', 'Sibling', 'Friend']),
77
- phone: `+${countries[country].code} ${emergencyPhone}`
89
+ phone: `+${countries[country].code} ${emergencyPhone}`,
78
90
  });
79
91
  }
80
92
 
@@ -113,15 +125,15 @@ export default function personal() {
113
125
  twitter: `@${social}`,
114
126
  facebook: `facebook.com/${social}`,
115
127
  linkedin: `linkedin.com/in/${social}`,
116
- instagram: `instagram.com/${social}`
128
+ instagram: `instagram.com/${social}`,
117
129
  },
118
130
  year_income: `${yearIncome} USD/year`,
119
131
  month_income: `${(yearIncome / 12).toFixed(2)} USD/month`,
120
- education: random(['High School', 'Bachelor\'s', 'Master\'s', 'PhD']),
132
+ education: random(['High School', "Bachelor's", "Master's", 'PhD']),
121
133
  work_experience: `${randomNumber(0, 20)} years`,
122
134
  health_status: random(['Healthy', 'Minor Issues', 'Chronic Conditions']),
123
135
  emergency_contacts: emergencyContacts,
124
136
  subscriptions,
125
137
  pets,
126
138
  };
127
- }
139
+ }
@@ -17,4 +17,4 @@ export default async function qrcode(url) {
17
17
  } catch (error) {
18
18
  throw new Error(`Failed to generate QR code: ${error.message}`);
19
19
  }
20
- }
20
+ }
@@ -30,7 +30,7 @@ export default function tic_tac_toe(action, params = {}) {
30
30
  const now = Date.now();
31
31
 
32
32
  // Rate limiting
33
- rateLimits[u] = (rateLimits[u] || []).filter(ts => now - ts < 10000);
33
+ rateLimits[u] = (rateLimits[u] || []).filter((ts) => now - ts < 10000);
34
34
  if (rateLimits[u].length > 50) {
35
35
  const remainingTime = Math.ceil((rateLimits[u][0] + 10000 - now) / 1000);
36
36
  throw new Error(`Rate limit exceeded. Try again in ${remainingTime} seconds.`);
@@ -70,12 +70,12 @@ function playMove(params, games, sessions, u, now) {
70
70
  moves: [],
71
71
  players: [],
72
72
  private: params.private || false,
73
- creation: Date.now()
73
+ creation: Date.now(),
74
74
  };
75
75
  const moves = games[game].moves;
76
76
 
77
77
  // Check if game is full
78
- const players = [...new Set(moves.map(play => play.username))];
78
+ const players = [...new Set(moves.map((play) => play.username))];
79
79
  if (players.length >= 2 && !players.includes(params.username)) {
80
80
  throw new Error('Game is full, you can only watch.');
81
81
  }
@@ -86,7 +86,7 @@ function playMove(params, games, sessions, u, now) {
86
86
  }
87
87
 
88
88
  // Check if move is already made
89
- if (moves.some(play => play.move === move)) {
89
+ if (moves.some((play) => play.move === move)) {
90
90
  throw new Error('Move already made. Please choose a different move.');
91
91
  }
92
92
 
@@ -99,8 +99,8 @@ function playMove(params, games, sessions, u, now) {
99
99
  if (result.winner || result.tie) {
100
100
  setTimeout(() => delete games[game], 600000);
101
101
  return {
102
- message: `Move sent successfully. ${result.winner ? result.winner + ' wins. ' + result.loser + ' loses.' : 'It\'s a tie.'}`,
103
- ...result
102
+ message: `Move sent successfully. ${result.winner ? result.winner + ' wins. ' + result.loser + ' loses.' : "It's a tie."}`,
103
+ ...result,
104
104
  };
105
105
  }
106
106
 
@@ -110,7 +110,9 @@ function playMove(params, games, sessions, u, now) {
110
110
  // Update session
111
111
  sessions[u] = sessions[u] || { user: session, last: now };
112
112
  sessions[u].last = now;
113
- setTimeout(() => { if (now - sessions[u].last >= 3600000) delete sessions[u]; }, 3600000);
113
+ setTimeout(() => {
114
+ if (now - sessions[u].last >= 3600000) delete sessions[u];
115
+ }, 3600000);
114
116
 
115
117
  return { message: 'Move sent successfully' };
116
118
  }
@@ -125,7 +127,7 @@ function fetchGame(params, games, u) {
125
127
  moves: [],
126
128
  players: [],
127
129
  private: params.private || false,
128
- creation: Date.now()
130
+ creation: Date.now(),
129
131
  };
130
132
  }
131
133
  if (!games[id].players.includes(u)) {
@@ -136,7 +138,7 @@ function fetchGame(params, games, u) {
136
138
  const players = games[id].players;
137
139
  const privateGame = games[id].private;
138
140
  const lastPlayer = moves.length ? moves[moves.length - 1].username : null;
139
- const turn = players.find(p => p !== lastPlayer) || players[0];
141
+ const turn = players.find((p) => p !== lastPlayer) || players[0];
140
142
  const status = players.length >= 2 ? 'ready' : 'waiting';
141
143
  const result = moves.length ? checkGame(moves) : {};
142
144
 
@@ -147,7 +149,7 @@ function fetchGame(params, games, u) {
147
149
  turn,
148
150
  status,
149
151
  private: privateGame,
150
- ...result
152
+ ...result,
151
153
  };
152
154
  }
153
155
 
@@ -167,7 +169,7 @@ function listGames(games) {
167
169
  // Only include active games (not finished)
168
170
  if (!isFinished) {
169
171
  const lastPlayer = game.moves.length ? game.moves[game.moves.length - 1].username : null;
170
- const turn = game.players.find(p => p !== lastPlayer) || game.players[0];
172
+ const turn = game.players.find((p) => p !== lastPlayer) || game.players[0];
171
173
  const status = game.players.length >= 2 ? 'ready' : 'waiting';
172
174
 
173
175
  publicGames.push({
@@ -177,7 +179,7 @@ function listGames(games) {
177
179
  moves: game.moves.length,
178
180
  turn,
179
181
  status,
180
- creation: game.creation || now
182
+ creation: game.creation || now,
181
183
  });
182
184
  }
183
185
  }
@@ -189,7 +191,7 @@ function listGames(games) {
189
191
  return {
190
192
  message: 'Public games available',
191
193
  count: publicGames.length,
192
- games: publicGames
194
+ games: publicGames,
193
195
  };
194
196
  }
195
197
 
@@ -198,14 +200,18 @@ function listGames(games) {
198
200
  */
199
201
  function generateGameId() {
200
202
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
201
- return Array.from(randomBytes(5)).map(b => chars[b % chars.length]).join('');
203
+ return Array.from(randomBytes(5))
204
+ .map((b) => chars[b % chars.length])
205
+ .join('');
202
206
  }
203
207
 
204
208
  /**
205
209
  * Check the game result
206
210
  */
207
211
  function checkGame(moves) {
208
- let board = Array(3).fill().map(() => Array(3).fill(null));
212
+ let board = Array(3)
213
+ .fill()
214
+ .map(() => Array(3).fill(null));
209
215
  let playerSymbols = {};
210
216
  let playersOrder = [];
211
217
 
@@ -228,9 +234,9 @@ function checkGame(moves) {
228
234
  return false;
229
235
  };
230
236
 
231
- let winner = Object.keys(playerSymbols).find(player => checkWinner(playerSymbols[player]));
237
+ let winner = Object.keys(playerSymbols).find((player) => checkWinner(playerSymbols[player]));
232
238
  let isTie = !winner && moves.length === 9;
233
- let loser = winner && playersOrder.length === 2 ? playersOrder.find(player => player !== winner) : null;
239
+ let loser = winner && playersOrder.length === 2 ? playersOrder.find((player) => player !== winner) : null;
234
240
 
235
241
  return { winner, loser, tie: isTie };
236
- }
242
+ }
@@ -11,16 +11,27 @@
11
11
  */
12
12
  export default function time(type = 'live', start, end, format, timezone) {
13
13
  const validFormats = [
14
- 'iso', 'utc', 'timestamp', 'locale', 'date', 'time',
15
- 'year', 'month', 'day', 'hour', 'minute', 'second',
16
- 'ms', 'dayOfWeek', 'dayOfYear', 'weekNumber',
17
- 'timezone', 'timezoneOffset'
14
+ 'iso',
15
+ 'utc',
16
+ 'timestamp',
17
+ 'locale',
18
+ 'date',
19
+ 'time',
20
+ 'year',
21
+ 'month',
22
+ 'day',
23
+ 'hour',
24
+ 'minute',
25
+ 'second',
26
+ 'ms',
27
+ 'dayOfWeek',
28
+ 'dayOfYear',
29
+ 'weekNumber',
30
+ 'timezone',
31
+ 'timezoneOffset',
18
32
  ];
19
33
 
20
- const validTimezones = [
21
- 'UTC', 'America/New_York', 'Europe/Paris',
22
- 'Asia/Tokyo', 'Australia/Sydney'
23
- ];
34
+ const validTimezones = ['UTC', 'America/New_York', 'Europe/Paris', 'Asia/Tokyo', 'Australia/Sydney'];
24
35
 
25
36
  // Input validation
26
37
  if (type !== 'live' && type !== 'random') {
@@ -61,9 +72,9 @@ export default function time(type = 'live', start, end, format, timezone) {
61
72
  ms: date.getMilliseconds(),
62
73
  dayOfWeek: date.getDay(),
63
74
  dayOfYear: Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 86400000),
64
- weekNumber: Math.ceil((((date - new Date(date.getFullYear(), 0, 0)) / 86400000) + 1) / 7),
75
+ weekNumber: Math.ceil(((date - new Date(date.getFullYear(), 0, 0)) / 86400000 + 1) / 7),
65
76
  timezone: tz,
66
- timezoneOffset: date.getTimezoneOffset()
77
+ timezoneOffset: date.getTimezoneOffset(),
67
78
  };
68
79
  };
69
80
 
@@ -84,4 +95,4 @@ export default function time(type = 'live', start, end, format, timezone) {
84
95
  const formats = getTimeFormats(now, tz);
85
96
 
86
97
  return format ? { date: formats[format] } : formats;
87
- }
98
+ }
@@ -0,0 +1,54 @@
1
+ import { randomBytes } from 'crypto';
2
+ import { v4 } from 'uuid';
3
+
4
+ /**
5
+ * Generate a random token of specified length and type.
6
+ *
7
+ * @param {number} len - Length of the token
8
+ * @param {string} type - Type of token to generate
9
+ * @returns {string} - The generated token
10
+ * @throws {Error} - If inputs are invalid
11
+ */
12
+ export default function token(len, type = 'alphanum') {
13
+ // Input validation
14
+ if (isNaN(len) || len < 12) {
15
+ throw new Error('Length must be a number greater than or equal to 12');
16
+ }
17
+
18
+ if (len > 4096) {
19
+ throw new Error('Length cannot exceed 4096');
20
+ }
21
+
22
+ // Helper function to generate token from character set
23
+ const genToken = (chars, length) => {
24
+ return Array.from({ length }, () => {
25
+ return chars[Math.floor(Math.random() * chars.length)];
26
+ }).join('');
27
+ };
28
+
29
+ // Token type definitions
30
+ const tokenTypes = {
31
+ alpha: () => genToken('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', len),
32
+ alphanum: () => genToken('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', len),
33
+ base64: () =>
34
+ randomBytes(Math.ceil(len * 0.75))
35
+ .toString('base64')
36
+ .slice(0, len),
37
+ hex: () =>
38
+ randomBytes(Math.ceil(len * 0.5))
39
+ .toString('hex')
40
+ .slice(0, len),
41
+ num: () => genToken('0123456789', len),
42
+ punct: () => genToken('!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~', len),
43
+ urlsafe: () => genToken('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_', len),
44
+ uuid: () => v4().replace(/-/g, '').slice(0, len),
45
+ };
46
+
47
+ // Generate token based on type or default to alphanum
48
+ if (!tokenTypes[type.toLowerCase()]) {
49
+ throw new Error(`Invalid token type. Valid types: ${Object.keys(tokenTypes).join(', ')}`);
50
+ }
51
+
52
+ // Generate token based on type or default to alphanum
53
+ return (tokenTypes[type.toLowerCase()] || tokenTypes.alphanum)();
54
+ }
@@ -0,0 +1,94 @@
1
+ import { random, randomNumber } from './utils.js';
2
+
3
+ /**
4
+ * Generate a random username with related information
5
+ *
6
+ * @returns {Object} Object containing username and component parts
7
+ */
8
+ export default function username() {
9
+ const adj = [
10
+ 'Happy',
11
+ 'Silly',
12
+ 'Clever',
13
+ 'Creative',
14
+ 'Brave',
15
+ 'Gentle',
16
+ 'Kind',
17
+ 'Funny',
18
+ 'Wise',
19
+ 'Charming',
20
+ 'Sincere',
21
+ 'Resourceful',
22
+ 'Patient',
23
+ 'Energetic',
24
+ 'Adventurous',
25
+ 'Ambitious',
26
+ 'Courageous',
27
+ 'Courteous',
28
+ 'Determined',
29
+ ];
30
+ const ani = [
31
+ 'Cat',
32
+ 'Dog',
33
+ 'Tiger',
34
+ 'Elephant',
35
+ 'Monkey',
36
+ 'Penguin',
37
+ 'Dolphin',
38
+ 'Lion',
39
+ 'Bear',
40
+ 'Fox',
41
+ 'Owl',
42
+ 'Giraffe',
43
+ 'Zebra',
44
+ 'Koala',
45
+ 'Rabbit',
46
+ 'Squirrel',
47
+ 'Panda',
48
+ 'Horse',
49
+ 'Wolf',
50
+ 'Eagle',
51
+ ];
52
+ const job = [
53
+ 'Writer',
54
+ 'Artist',
55
+ 'Musician',
56
+ 'Explorer',
57
+ 'Scientist',
58
+ 'Engineer',
59
+ 'Athlete',
60
+ 'Chef',
61
+ 'Doctor',
62
+ 'Teacher',
63
+ 'Lawyer',
64
+ 'Entrepreneur',
65
+ 'Actor',
66
+ 'Dancer',
67
+ 'Photographer',
68
+ 'Architect',
69
+ 'Pilot',
70
+ 'Designer',
71
+ 'Journalist',
72
+ 'Veterinarian',
73
+ ];
74
+
75
+ const nombre = randomNumber(0, 99);
76
+ const choix = {
77
+ adj_num: () => random(adj) + nombre,
78
+ ani_num: () => random(ani) + nombre,
79
+ pro_num: () => random(job) + nombre,
80
+ adj_ani: () => random(adj) + random(ani),
81
+ adj_ani_num: () => random(adj) + random(ani) + nombre,
82
+ adj_pro: () => random(adj) + random(job),
83
+ pro_ani: () => random(job) + random(ani),
84
+ pro_ani_num: () => random(job) + random(ani) + nombre,
85
+ };
86
+
87
+ return {
88
+ username: choix[random(Object.keys(choix))](),
89
+ number: nombre,
90
+ adjective: random(adj),
91
+ animal: random(ani),
92
+ job: random(job),
93
+ };
94
+ }
@@ -65,7 +65,7 @@ export function envList(key) {
65
65
  * @throws {Error} - If rate limit is exceeded
66
66
  */
67
67
  export function checkRateLimit(rateLimits, userId, timestamp, window = 10000, limit = 50) {
68
- rateLimits[userId] = (rateLimits[userId] || []).filter(ts => timestamp - ts < window);
68
+ rateLimits[userId] = (rateLimits[userId] || []).filter((ts) => timestamp - ts < window);
69
69
 
70
70
  if (rateLimits[userId].length > limit) {
71
71
  const remainingTime = Math.ceil((rateLimits[userId][0] + window - timestamp) / 1000);
@@ -74,4 +74,4 @@ export function checkRateLimit(rateLimits, userId, timestamp, window = 10000, li
74
74
 
75
75
  rateLimits[userId].push(timestamp);
76
76
  return false;
77
- }
77
+ }
@@ -12,4 +12,4 @@ export { default as qrcode } from './v3/qrcode.js';
12
12
  export { default as tic_tac_toe } from './v3/tic_tac_toe.js';
13
13
  export { default as time } from './v3/time.js';
14
14
  export { default as token } from './v3/token.js';
15
- export { default as username } from './v3/username.js';
15
+ export { default as username } from './v3/username.js';