@20syldev/api 4.8.0 → 4.9.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 (109) hide show
  1. package/README.md +84 -47
  2. package/package.json +2 -1
  3. package/.github/FUNDING.yml +0 -1
  4. package/.prettierrc +0 -7
  5. package/eslint.config.js +0 -24
  6. package/robots.txt +0 -74
  7. package/src/app.ts +0 -53
  8. package/src/config/env.ts +0 -87
  9. package/src/config/plans.ts +0 -61
  10. package/src/config/versions.ts +0 -121
  11. package/src/constants.ts +0 -61
  12. package/src/favicon.ico +0 -0
  13. package/src/middleware/cors.ts +0 -23
  14. package/src/middleware/error.ts +0 -16
  15. package/src/middleware/json.ts +0 -9
  16. package/src/middleware/logger.ts +0 -32
  17. package/src/middleware/ratelimit.ts +0 -89
  18. package/src/middleware/version.ts +0 -40
  19. package/src/modules/v3/algorithms.js +0 -218
  20. package/src/modules/v3/captcha.js +0 -60
  21. package/src/modules/v3/chat.js +0 -111
  22. package/src/modules/v3/color.js +0 -60
  23. package/src/modules/v3/convert.js +0 -39
  24. package/src/modules/v3/domain.js +0 -86
  25. package/src/modules/v3/hash.js +0 -16
  26. package/src/modules/v3/hyperplanning.js +0 -56
  27. package/src/modules/v3/levenshtein.js +0 -46
  28. package/src/modules/v3/personal.js +0 -139
  29. package/src/modules/v3/qrcode.js +0 -20
  30. package/src/modules/v3/tic_tac_toe.js +0 -242
  31. package/src/modules/v3/time.js +0 -98
  32. package/src/modules/v3/token.js +0 -54
  33. package/src/modules/v3/username.js +0 -94
  34. package/src/modules/v3/utils.js +0 -77
  35. package/src/modules/v3.js +0 -15
  36. package/src/modules/v4/address.ts +0 -412
  37. package/src/modules/v4/agent.ts +0 -104
  38. package/src/modules/v4/algorithms.ts +0 -276
  39. package/src/modules/v4/captcha.ts +0 -114
  40. package/src/modules/v4/chat.ts +0 -130
  41. package/src/modules/v4/color.ts +0 -75
  42. package/src/modules/v4/convert.ts +0 -127
  43. package/src/modules/v4/cron.ts +0 -221
  44. package/src/modules/v4/dice.ts +0 -46
  45. package/src/modules/v4/domain.ts +0 -86
  46. package/src/modules/v4/encode.ts +0 -241
  47. package/src/modules/v4/geo.ts +0 -64
  48. package/src/modules/v4/hash.ts +0 -32
  49. package/src/modules/v4/hyperplanning.ts +0 -93
  50. package/src/modules/v4/ip.ts +0 -134
  51. package/src/modules/v4/levenshtein.ts +0 -46
  52. package/src/modules/v4/palette.ts +0 -71
  53. package/src/modules/v4/password.ts +0 -379
  54. package/src/modules/v4/personal.ts +0 -140
  55. package/src/modules/v4/placeholder.ts +0 -197
  56. package/src/modules/v4/qrcode.ts +0 -121
  57. package/src/modules/v4/regex.ts +0 -67
  58. package/src/modules/v4/statistics.ts +0 -62
  59. package/src/modules/v4/text.ts +0 -330
  60. package/src/modules/v4/tic_tac_toe.ts +0 -264
  61. package/src/modules/v4/time.ts +0 -149
  62. package/src/modules/v4/token.ts +0 -53
  63. package/src/modules/v4/username.ts +0 -94
  64. package/src/modules/v4/validate.ts +0 -76
  65. package/src/modules/v4.ts +0 -29
  66. package/src/routes/delete.ts +0 -72
  67. package/src/routes/get.ts +0 -856
  68. package/src/routes/index.ts +0 -59
  69. package/src/routes/patch.ts +0 -45
  70. package/src/routes/post.ts +0 -209
  71. package/src/storage/index.ts +0 -16
  72. package/src/types/express.d.ts +0 -17
  73. package/src/types/storage.ts +0 -48
  74. package/src/utils/colors.ts +0 -91
  75. package/src/utils/helpers.ts +0 -90
  76. package/src/utils/response.ts +0 -28
  77. package/tests/integration/api.test.ts +0 -772
  78. package/tests/tsconfig.json +0 -3
  79. package/tests/unit/address.test.ts +0 -84
  80. package/tests/unit/agent.test.ts +0 -113
  81. package/tests/unit/algorithms.test.ts +0 -121
  82. package/tests/unit/captcha.test.ts +0 -62
  83. package/tests/unit/chat.test.ts +0 -54
  84. package/tests/unit/color.test.ts +0 -54
  85. package/tests/unit/convert.test.ts +0 -68
  86. package/tests/unit/cron.test.ts +0 -110
  87. package/tests/unit/dice.test.ts +0 -58
  88. package/tests/unit/domain.test.ts +0 -48
  89. package/tests/unit/encode.test.ts +0 -109
  90. package/tests/unit/geo.test.ts +0 -46
  91. package/tests/unit/hash.test.ts +0 -45
  92. package/tests/unit/hyperplanning.test.ts +0 -97
  93. package/tests/unit/ip.test.ts +0 -140
  94. package/tests/unit/levenshtein.test.ts +0 -35
  95. package/tests/unit/palette.test.ts +0 -54
  96. package/tests/unit/password.test.ts +0 -86
  97. package/tests/unit/personal.test.ts +0 -66
  98. package/tests/unit/placeholder.test.ts +0 -58
  99. package/tests/unit/qrcode.test.ts +0 -83
  100. package/tests/unit/regex.test.ts +0 -95
  101. package/tests/unit/statistics.test.ts +0 -58
  102. package/tests/unit/text.test.ts +0 -108
  103. package/tests/unit/tic_tac_toe.test.ts +0 -56
  104. package/tests/unit/time.test.ts +0 -115
  105. package/tests/unit/token.test.ts +0 -62
  106. package/tests/unit/username.test.ts +0 -35
  107. package/tests/unit/validate.test.ts +0 -72
  108. package/tsconfig.json +0 -17
  109. package/tsconfig.test.json +0 -9
@@ -1,127 +0,0 @@
1
- type ConversionFn = (val: number) => number;
2
-
3
- const TEMPERATURE_UNITS = new Set(['celsius', 'fahrenheit', 'kelvin']);
4
- const ABSOLUTE_ZERO: Record<string, number> = { celsius: -273.15, fahrenheit: -459.67, kelvin: 0 };
5
-
6
- const conversions: Record<string, Record<string, ConversionFn>> = {
7
- // Temperature
8
- celsius: {
9
- fahrenheit: (v) => (v * 9) / 5 + 32,
10
- kelvin: (v) => v + 273.15,
11
- },
12
- fahrenheit: {
13
- celsius: (v) => ((v - 32) * 5) / 9,
14
- kelvin: (v) => ((v - 32) * 5) / 9 + 273.15,
15
- },
16
- kelvin: {
17
- celsius: (v) => v - 273.15,
18
- fahrenheit: (v) => ((v - 273.15) * 9) / 5 + 32,
19
- },
20
-
21
- // Length
22
- km: {
23
- mi: (v) => v * 0.621371,
24
- m: (v) => v * 1000,
25
- ft: (v) => v * 3280.84,
26
- cm: (v) => v * 100000,
27
- in: (v) => v * 39370.1,
28
- yd: (v) => v * 1093.61,
29
- },
30
- mi: {
31
- km: (v) => v * 1.60934,
32
- m: (v) => v * 1609.34,
33
- ft: (v) => v * 5280,
34
- cm: (v) => v * 160934,
35
- in: (v) => v * 63360,
36
- yd: (v) => v * 1760,
37
- },
38
- m: {
39
- km: (v) => v / 1000,
40
- mi: (v) => v * 0.000621371,
41
- ft: (v) => v * 3.28084,
42
- cm: (v) => v * 100,
43
- in: (v) => v * 39.3701,
44
- yd: (v) => v * 1.09361,
45
- },
46
- ft: {
47
- km: (v) => v * 0.0003048,
48
- mi: (v) => v / 5280,
49
- m: (v) => v * 0.3048,
50
- cm: (v) => v * 30.48,
51
- in: (v) => v * 12,
52
- yd: (v) => v / 3,
53
- },
54
- cm: {
55
- km: (v) => v / 100000,
56
- mi: (v) => v / 160934,
57
- m: (v) => v / 100,
58
- ft: (v) => v / 30.48,
59
- in: (v) => v / 2.54,
60
- yd: (v) => v / 91.44,
61
- },
62
- in: {
63
- km: (v) => v / 39370.1,
64
- mi: (v) => v / 63360,
65
- m: (v) => v * 0.0254,
66
- ft: (v) => v / 12,
67
- cm: (v) => v * 2.54,
68
- yd: (v) => v / 36,
69
- },
70
- yd: {
71
- km: (v) => v * 0.0009144,
72
- mi: (v) => v / 1760,
73
- m: (v) => v * 0.9144,
74
- ft: (v) => v * 3,
75
- cm: (v) => v * 91.44,
76
- in: (v) => v * 36,
77
- },
78
-
79
- // Weight
80
- kg: { lb: (v) => v * 2.20462, oz: (v) => v * 35.274, g: (v) => v * 1000, ton: (v) => v / 1000 },
81
- lb: { kg: (v) => v * 0.453592, oz: (v) => v * 16, g: (v) => v * 453.592, ton: (v) => v * 0.000453592 },
82
- oz: { kg: (v) => v * 0.0283495, lb: (v) => v / 16, g: (v) => v * 28.3495, ton: (v) => v * 0.0000283495 },
83
- g: { kg: (v) => v / 1000, lb: (v) => v * 0.00220462, oz: (v) => v * 0.035274, ton: (v) => v / 1000000 },
84
- ton: { kg: (v) => v * 1000, lb: (v) => v * 2204.62, oz: (v) => v * 35274, g: (v) => v * 1000000 },
85
-
86
- // Data
87
- b: { kb: (v) => v / 1024, mb: (v) => v / 1048576, gb: (v) => v / 1073741824, tb: (v) => v / 1099511627776 },
88
- kb: { b: (v) => v * 1024, mb: (v) => v / 1024, gb: (v) => v / 1048576, tb: (v) => v / 1073741824 },
89
- mb: { b: (v) => v * 1048576, kb: (v) => v * 1024, gb: (v) => v / 1024, tb: (v) => v / 1048576 },
90
- gb: { b: (v) => v * 1073741824, kb: (v) => v * 1048576, mb: (v) => v * 1024, tb: (v) => v / 1024 },
91
- tb: { b: (v) => v * 1099511627776, kb: (v) => v * 1073741824, mb: (v) => v * 1048576, gb: (v) => v * 1024 },
92
-
93
- // Speed
94
- 'km/h': { mph: (v) => v * 0.621371, 'm/s': (v) => v / 3.6, knots: (v) => v * 0.539957 },
95
- mph: { 'km/h': (v) => v * 1.60934, 'm/s': (v) => v * 0.44704, knots: (v) => v * 0.868976 },
96
- 'm/s': { 'km/h': (v) => v * 3.6, mph: (v) => v * 2.23694, knots: (v) => v * 1.94384 },
97
- knots: { 'km/h': (v) => v * 1.852, mph: (v) => v * 1.15078, 'm/s': (v) => v * 0.514444 },
98
- };
99
-
100
- /**
101
- * Converts a numeric value from one unit to another.
102
- *
103
- * @param value - The numeric value to convert
104
- * @param from - The source unit (e.g. "km", "celsius", "kg")
105
- * @param to - The target unit (e.g. "mi", "fahrenheit", "lb")
106
- * @returns Object with source unit, target unit, original value, and converted result
107
- * @throws Error if the conversion pair is unsupported, the value is NaN, or the temperature is below absolute zero
108
- */
109
- export default function convert(
110
- value: number,
111
- from: string,
112
- to: string,
113
- ): { from: string; to: string; value: number; result: number } {
114
- const fromKey = from.toLowerCase();
115
- const toKey = to.toLowerCase();
116
- const convertFn = conversions[fromKey]?.[toKey];
117
-
118
- if (!convertFn) throw new Error('Invalid conversion unit');
119
- if (isNaN(value)) throw new Error('Value must be a number');
120
-
121
- if (TEMPERATURE_UNITS.has(fromKey)) {
122
- const minValue = ABSOLUTE_ZERO[fromKey]!;
123
- if (value < minValue) throw new Error('Value must be greater than absolute zero');
124
- }
125
-
126
- return { from, to, value, result: convertFn(value) };
127
- }
@@ -1,221 +0,0 @@
1
- import { MAX_CRON_ITERATIONS, MAX_CRON_RESULTS } from '../../constants.js';
2
- import { VALID_TIMEZONES } from './time.js';
3
-
4
- type Timezone = (typeof VALID_TIMEZONES)[number];
5
-
6
- const FIELD_RANGES = [
7
- { min: 0, max: 59 }, // minute
8
- { min: 0, max: 23 }, // hour
9
- { min: 1, max: 31 }, // day of month
10
- { min: 1, max: 12 }, // month
11
- { min: 0, max: 7 }, // day of week (0 and 7 = Sunday)
12
- ] as const;
13
-
14
- const DOW_NAMES: Record<string, number> = {
15
- Sunday: 0,
16
- Monday: 1,
17
- Tuesday: 2,
18
- Wednesday: 3,
19
- Thursday: 4,
20
- Friday: 5,
21
- Saturday: 6,
22
- };
23
-
24
- const DOW_DISPLAY = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
25
-
26
- export interface CronResult {
27
- expression: string;
28
- description: string;
29
- next: string[];
30
- timezone: string;
31
- }
32
-
33
- function parseField(field: string, range: { min: number; max: number }): Set<number> {
34
- const result = new Set<number>();
35
-
36
- for (const part of field.split(',')) {
37
- if (part === '*') {
38
- for (let i = range.min; i <= range.max; i++) result.add(i);
39
- } else if (part.startsWith('*/')) {
40
- const step = parseInt(part.slice(2), 10);
41
- if (isNaN(step) || step < 1) throw new Error(`Invalid step in "${part}"`);
42
- for (let i = range.min; i <= range.max; i += step) result.add(i);
43
- } else if (part.includes('-')) {
44
- const [s, e] = part.split('-');
45
- const start = parseInt(s!, 10);
46
- const end = parseInt(e!, 10);
47
- if (isNaN(start) || isNaN(end) || start < range.min || end > range.max || start > end) {
48
- throw new Error(`Invalid range "${part}" (valid: ${range.min}-${range.max})`);
49
- }
50
- for (let i = start; i <= end; i++) result.add(i);
51
- } else {
52
- const val = parseInt(part, 10);
53
- if (isNaN(val) || val < range.min || val > range.max) {
54
- throw new Error(`Invalid value "${part}" (valid: ${range.min}-${range.max})`);
55
- }
56
- result.add(val);
57
- }
58
- }
59
-
60
- return result;
61
- }
62
-
63
- function getComponents(
64
- date: Date,
65
- formatter: Intl.DateTimeFormat,
66
- ): { minute: number; hour: number; dom: number; month: number; dow: number } {
67
- const parts = Object.fromEntries(formatter.formatToParts(date).map((p) => [p.type, p.value]));
68
- return {
69
- minute: parseInt(parts.minute!, 10),
70
- hour: parseInt(parts.hour!, 10) % 24,
71
- dom: parseInt(parts.day!, 10),
72
- month: parseInt(parts.month!, 10),
73
- dow: DOW_NAMES[parts.weekday!] ?? 0,
74
- };
75
- }
76
-
77
- function pad(n: number): string {
78
- return String(n).padStart(2, '0');
79
- }
80
-
81
- function formatDow(field: string): string {
82
- if (field === '1-5') return 'Monday through Friday';
83
- if (field === '0' || field === '7') return 'Sunday';
84
- if (field === '6') return 'Saturday';
85
- const n = parseInt(field, 10);
86
- if (!isNaN(n)) return DOW_DISPLAY[n % 7] ?? field;
87
- return field;
88
- }
89
-
90
- function describe(fields: string[]): string {
91
- const [mF, hF, domF, monthF, dowF] = fields as [string, string, string, string, string];
92
-
93
- const isAll = (f: string) => f === '*';
94
- const isFixed = (f: string) => /^\d+$/.test(f);
95
- const isStep = (f: string) => /^\*\/\d+$/.test(f);
96
-
97
- // Every minute
98
- if (isAll(mF) && isAll(hF) && isAll(domF) && isAll(monthF) && isAll(dowF)) {
99
- return 'Every minute';
100
- }
101
-
102
- // Every N minutes (whole day, every day)
103
- if (isStep(mF) && isAll(hF) && isAll(domF) && isAll(monthF) && isAll(dowF)) {
104
- const n = mF.slice(2);
105
- return `Every ${n} minute${n === '1' ? '' : 's'}`;
106
- }
107
-
108
- // Every hour at minute 0
109
- if (mF === '0' && isAll(hF) && isAll(domF) && isAll(monthF) && isAll(dowF)) {
110
- return 'Every hour';
111
- }
112
-
113
- // Every N hours at minute 0
114
- if (mF === '0' && isStep(hF) && isAll(domF) && isAll(monthF) && isAll(dowF)) {
115
- const n = hF.slice(2);
116
- return `Every ${n} hour${n === '1' ? '' : 's'}`;
117
- }
118
-
119
- // At specific time daily
120
- if (isFixed(mF) && isFixed(hF) && isAll(domF) && isAll(monthF) && isAll(dowF)) {
121
- return `At ${pad(parseInt(hF))}:${pad(parseInt(mF))} daily`;
122
- }
123
-
124
- // At specific time on specific weekday(s)
125
- if (isFixed(mF) && isFixed(hF) && isAll(domF) && isAll(monthF) && !isAll(dowF)) {
126
- return `At ${pad(parseInt(hF))}:${pad(parseInt(mF))}, ${formatDow(dowF)}`;
127
- }
128
-
129
- // At specific time on specific day of month
130
- if (isFixed(mF) && isFixed(hF) && isFixed(domF) && isAll(monthF) && isAll(dowF)) {
131
- return `At ${pad(parseInt(hF))}:${pad(parseInt(mF))}, on day ${domF} of the month`;
132
- }
133
-
134
- // Every N minutes, within hour range, optionally filtered by weekday
135
- if (isStep(mF) && !isAll(hF) && isAll(domF) && isAll(monthF)) {
136
- const n = mF.slice(2);
137
- const parts = [`Every ${n} minute${n === '1' ? '' : 's'}`];
138
- if (hF.includes('-')) {
139
- const [h1, h2] = hF.split('-');
140
- parts.push(`between ${pad(parseInt(h1!))}:00 and ${pad(parseInt(h2!))}:59`);
141
- }
142
- if (!isAll(dowF)) parts.push(formatDow(dowF));
143
- return parts.join(', ');
144
- }
145
-
146
- return `At cron schedule: ${fields.join(' ')}`;
147
- }
148
-
149
- /**
150
- * Parses a cron expression and returns the next scheduled execution dates.
151
- *
152
- * @param expr - Cron expression with 5 space-separated fields (minute hour dom month dow)
153
- * @param count - Number of next executions to return (1–20, default 5)
154
- * @param from - Starting date in ISO 8601 format (defaults to now)
155
- * @param timezone - Timezone to evaluate the expression in (default "UTC")
156
- * @returns Parsed expression with description and list of next execution timestamps
157
- * @throws Error if the expression is invalid, count is out of range, or timezone is unsupported
158
- */
159
- export default function cron(expr: string, count: number = 5, from?: string, timezone: string = 'UTC'): CronResult {
160
- if (!expr) throw new Error('Please provide a cron expression (?expr=* * * * *)');
161
-
162
- if (!VALID_TIMEZONES.includes(timezone as Timezone)) {
163
- throw new Error(`Please provide a valid timezone. Options: ${VALID_TIMEZONES.join(', ')}`);
164
- }
165
-
166
- const fields = expr.trim().split(/\s+/);
167
- if (fields.length !== 5) {
168
- throw new Error('Cron expression must have exactly 5 fields (minute hour dom month dow)');
169
- }
170
-
171
- if (count < 1 || count > MAX_CRON_RESULTS) {
172
- throw new Error(`Count must be between 1 and ${MAX_CRON_RESULTS}`);
173
- }
174
-
175
- const fromMs = from ? new Date(from).getTime() : Date.now();
176
- if (from && isNaN(fromMs)) throw new Error('Please provide a valid from date (ISO 8601)');
177
-
178
- const sets = fields.map((f, i) => parseField(f, FIELD_RANGES[i]!));
179
- const [minuteSet, hourSet, domSet, monthSet, dowSet] = sets as [
180
- Set<number>,
181
- Set<number>,
182
- Set<number>,
183
- Set<number>,
184
- Set<number>,
185
- ];
186
-
187
- // Normalize DOW: treat 7 as Sunday (0)
188
- if (dowSet.has(7)) {
189
- dowSet.add(0);
190
- dowSet.delete(7);
191
- }
192
-
193
- const formatter = new Intl.DateTimeFormat('en-US', {
194
- timeZone: timezone,
195
- month: 'numeric',
196
- day: 'numeric',
197
- hour: 'numeric',
198
- minute: 'numeric',
199
- weekday: 'long',
200
- hour12: false,
201
- });
202
-
203
- // Always start from the next minute (never include the current minute)
204
- let currentMs = (Math.floor(fromMs / 60000) + 1) * 60000;
205
-
206
- const next: string[] = [];
207
- let iterations = 0;
208
-
209
- while (next.length < count && iterations < MAX_CRON_ITERATIONS) {
210
- const { minute, hour, dom, month, dow } = getComponents(new Date(currentMs), formatter);
211
-
212
- if (minuteSet.has(minute) && hourSet.has(hour) && domSet.has(dom) && monthSet.has(month) && dowSet.has(dow)) {
213
- next.push(new Date(currentMs).toISOString());
214
- }
215
-
216
- currentMs += 60000;
217
- iterations++;
218
- }
219
-
220
- return { expression: expr.trim(), description: describe(fields), next, timezone };
221
- }
@@ -1,46 +0,0 @@
1
- export interface DiceResult {
2
- roll: string;
3
- count: number;
4
- sides: number;
5
- modifier: number;
6
- results: number[];
7
- total: number;
8
- }
9
-
10
- /**
11
- * Rolls dice using standard tabletop notation and returns individual results with a total.
12
- *
13
- * @param roll - Dice notation string (e.g. "2d6+3", "d20", "4d8-1")
14
- * @returns Roll breakdown including count, sides, modifier, individual results, and total
15
- * @throws Error if the notation is missing, invalid, or out of bounds
16
- */
17
- export default function dice(roll: string): DiceResult {
18
- if (!roll) throw new Error('A roll notation is required (e.g. 2d6+3)');
19
- if (typeof roll !== 'string') throw new Error('Roll must be a string');
20
-
21
- const match = /^(\d*)d(\d+)([+-]\d+)?$/i.exec(roll.trim().replace(/\s+/g, '+'));
22
- if (!match) throw new Error('Invalid notation. Use NdX or NdX+M (e.g. 2d6+3)');
23
-
24
- const count = match[1] ? parseInt(match[1], 10) : 1;
25
- const sides = parseInt(match[2]!, 10);
26
- const modifier = match[3] ? parseInt(match[3], 10) : 0;
27
-
28
- if (count < 1 || count > 100) throw new Error('Number of dice must be between 1 and 100');
29
- if (sides < 2 || sides > 1000) throw new Error('Number of sides must be between 2 and 1000');
30
-
31
- const results: number[] = [];
32
- for (let i = 0; i < count; i++) {
33
- results.push(1 + Math.floor(Math.random() * sides));
34
- }
35
-
36
- const total = results.reduce((a, b) => a + b, 0) + modifier;
37
-
38
- return {
39
- roll: `${count}d${sides}${modifier ? (modifier > 0 ? `+${modifier}` : modifier) : ''}`,
40
- count,
41
- sides,
42
- modifier,
43
- results,
44
- total,
45
- };
46
- }
@@ -1,86 +0,0 @@
1
- import { genIP, random } from '../../utils/helpers.js';
2
-
3
- /**
4
- * Generates a randomized fictional domain profile with metadata.
5
- *
6
- * @returns Object containing domain name, IP addresses, DNS info, SEO score, and other domain attributes
7
- */
8
- export default function domain(): Record<string, unknown> {
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
- ];
59
-
60
- const domainName = `${random(domains)}${random(tlds)}`;
61
- const fulldomain = `${random(subdomains)}${domainName}`;
62
-
63
- const ips = Array.from({ length: Math.floor(Math.random() * 3) + 1 }, genIP);
64
- const dns = Array.from({ length: Math.floor(Math.random() * 5) + 1 }, genIP);
65
-
66
- return {
67
- domain: domainName,
68
- full_domain: fulldomain,
69
- ip_address: ips,
70
- ssl_certified: Math.random() > 0.5,
71
- hosting_provider: random(['AWS', 'Bluehost', 'DigitalOcean', 'GitHub', 'HostGator', 'Render', 'SiteGround']),
72
- dns_servers: dns,
73
- dns_provider: random(['AWS Route 53', 'Cloudflare', 'GoDaddy', 'Google DNS', 'Namecheap']),
74
- traffic: `${Math.floor(Math.random() * 10000)} visits/day`,
75
- seo_score: Math.floor(Math.random() * 100),
76
- page_rank: Math.floor(Math.random() * 10),
77
- country: random(['Australia', 'Canada', 'France', 'Germany', 'India', 'Japan', 'UK', 'USA']),
78
- website_type: random(['Blog', 'Community', 'Corporate', 'Educational', 'E-commerce', 'Personal', 'Portfolio']),
79
- random_name: domainName.split('.')[0],
80
- random_subdomain: fulldomain.split('.')[0],
81
- random_tld: domainName.split('.').pop(),
82
- backlinks_count: Math.floor(Math.random() * 1000),
83
- creation_date: new Date(Date.now() - Math.floor(Math.random() * 10000000000)).toISOString(),
84
- expiration_date: new Date(Date.now() + Math.floor(Math.random() * 10000000000)).toISOString(),
85
- };
86
- }