@20syldev/api 3.4.5 → 3.4.6
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.
- package/.github/FUNDING.yml +1 -1
- package/.github/workflows/publish.yml +27 -27
- package/LICENSE +27 -27
- package/README.md +110 -110
- package/app.js +850 -842
- package/modules/v3/algorithms.js +217 -217
- package/modules/v3/captcha.js +54 -54
- package/modules/v3/chat.js +108 -108
- package/modules/v3/color.js +40 -40
- package/modules/v3/convert.js +38 -38
- package/modules/v3/domain.js +38 -38
- package/modules/v3/hash.js +15 -15
- package/modules/v3/hyperplanning.js +54 -50
- package/modules/v3/levenshtein.js +45 -45
- package/modules/v3/personal.js +126 -126
- package/modules/v3/qrcode.js +19 -19
- package/modules/v3/tic_tac_toe.js +235 -235
- package/modules/v3/time.js +86 -86
- package/modules/v3/token.js +47 -47
- package/modules/v3/username.js +31 -31
- package/modules/v3/utils.js +76 -65
- package/modules/v3.js +14 -14
- package/package.json +53 -53
- package/robots.txt +73 -73
package/modules/v3/chat.js
CHANGED
|
@@ -1,109 +1,109 @@
|
|
|
1
|
-
import { checkRateLimit } from "./utils.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Manages a chat system with public and private messages
|
|
5
|
-
*
|
|
6
|
-
* @param {string} action - The action to perform ('message' or 'private')
|
|
7
|
-
* @param {Object} params - The parameters for the action
|
|
8
|
-
* @returns {Object} - The result of the action
|
|
9
|
-
* @throws {Error} - If parameters are invalid
|
|
10
|
-
*/
|
|
11
|
-
export default function chat(action, params = {}) {
|
|
12
|
-
// In-memory storage
|
|
13
|
-
const storage = params.storage || {};
|
|
14
|
-
|
|
15
|
-
// Initialize storage
|
|
16
|
-
storage.messages ??= [];
|
|
17
|
-
storage.privateChats ??= {};
|
|
18
|
-
storage.sessions ??= {};
|
|
19
|
-
storage.rateLimits ??= {};
|
|
20
|
-
|
|
21
|
-
// Reference the storage properties
|
|
22
|
-
const { messages, privateChats, sessions, rateLimits } = storage;
|
|
23
|
-
|
|
24
|
-
// Input validation for common parameters
|
|
25
|
-
if (!params.username) throw new Error('Please provide a username');
|
|
26
|
-
|
|
27
|
-
const u = params.username.toLowerCase();
|
|
28
|
-
const now = Date.now();
|
|
29
|
-
|
|
30
|
-
// Rate limiting
|
|
31
|
-
checkRateLimit(rateLimits, u, now);
|
|
32
|
-
|
|
33
|
-
// Handle different actions
|
|
34
|
-
if (action === 'message') {
|
|
35
|
-
return sendMessage(params, messages, privateChats, sessions, u, now);
|
|
36
|
-
} else if (action === 'private') {
|
|
37
|
-
return getPrivateChat(params, privateChats);
|
|
38
|
-
} else if (action === 'fetch') {
|
|
39
|
-
return fetchMessages(messages);
|
|
40
|
-
} else {
|
|
41
|
-
throw new Error('Invalid action. Use "message", "private", or "fetch"');
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Send a new message
|
|
47
|
-
*/
|
|
48
|
-
function sendMessage(params, messages, privateChats, sessions, u, now) {
|
|
49
|
-
const { message, session, token } = params;
|
|
50
|
-
|
|
51
|
-
// Input validation for message action
|
|
52
|
-
if (!message) throw new Error('Please provide a message');
|
|
53
|
-
if (!session) throw new Error('Please provide a valid session ID');
|
|
54
|
-
|
|
55
|
-
// Session validation
|
|
56
|
-
if (sessions[u] && sessions[u].user !== session) {
|
|
57
|
-
throw new Error('Session ID mismatch');
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Create message object
|
|
61
|
-
const msg = {
|
|
62
|
-
username: params.username,
|
|
63
|
-
message,
|
|
64
|
-
timestamp: params.timestamp || new Date().toISOString()
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
// Store message based on whether it's private or public
|
|
68
|
-
if (token) {
|
|
69
|
-
privateChats[token] = privateChats[token] || [];
|
|
70
|
-
privateChats[token].push(msg);
|
|
71
|
-
setTimeout(() => { delete privateChats[token]; }, 3600000);
|
|
72
|
-
} else {
|
|
73
|
-
messages.push(msg);
|
|
74
|
-
setTimeout(() => messages.splice(messages.indexOf(msg), 1), 3600000);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Update session
|
|
78
|
-
sessions[u] = sessions[u] || { user: session, last: now };
|
|
79
|
-
sessions[u].last = now;
|
|
80
|
-
|
|
81
|
-
setTimeout(() => {
|
|
82
|
-
if (now - sessions[u].last >= 3600000) delete sessions[u];
|
|
83
|
-
}, 3600000);
|
|
84
|
-
|
|
85
|
-
return { message: 'Message sent successfully' };
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Get private chat messages
|
|
90
|
-
*/
|
|
91
|
-
function getPrivateChat(params, privateChats) {
|
|
92
|
-
const { token } = params;
|
|
93
|
-
|
|
94
|
-
// Input validation for private action
|
|
95
|
-
if (!token) throw new Error('Please provide a valid token');
|
|
96
|
-
|
|
97
|
-
// Return messages if token exists
|
|
98
|
-
if (privateChats[token]) return privateChats[token];
|
|
99
|
-
|
|
100
|
-
throw new Error('Invalid or expired token.');
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Fetch all public messages
|
|
105
|
-
*/
|
|
106
|
-
function fetchMessages(messages) {
|
|
107
|
-
if (messages.length > 0) return messages;
|
|
108
|
-
throw new Error('No messages stored.');
|
|
1
|
+
import { checkRateLimit } from "./utils.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Manages a chat system with public and private messages
|
|
5
|
+
*
|
|
6
|
+
* @param {string} action - The action to perform ('message' or 'private')
|
|
7
|
+
* @param {Object} params - The parameters for the action
|
|
8
|
+
* @returns {Object} - The result of the action
|
|
9
|
+
* @throws {Error} - If parameters are invalid
|
|
10
|
+
*/
|
|
11
|
+
export default function chat(action, params = {}) {
|
|
12
|
+
// In-memory storage
|
|
13
|
+
const storage = params.storage || {};
|
|
14
|
+
|
|
15
|
+
// Initialize storage
|
|
16
|
+
storage.messages ??= [];
|
|
17
|
+
storage.privateChats ??= {};
|
|
18
|
+
storage.sessions ??= {};
|
|
19
|
+
storage.rateLimits ??= {};
|
|
20
|
+
|
|
21
|
+
// Reference the storage properties
|
|
22
|
+
const { messages, privateChats, sessions, rateLimits } = storage;
|
|
23
|
+
|
|
24
|
+
// Input validation for common parameters
|
|
25
|
+
if (!params.username) throw new Error('Please provide a username');
|
|
26
|
+
|
|
27
|
+
const u = params.username.toLowerCase();
|
|
28
|
+
const now = Date.now();
|
|
29
|
+
|
|
30
|
+
// Rate limiting
|
|
31
|
+
checkRateLimit(rateLimits, u, now);
|
|
32
|
+
|
|
33
|
+
// Handle different actions
|
|
34
|
+
if (action === 'message') {
|
|
35
|
+
return sendMessage(params, messages, privateChats, sessions, u, now);
|
|
36
|
+
} else if (action === 'private') {
|
|
37
|
+
return getPrivateChat(params, privateChats);
|
|
38
|
+
} else if (action === 'fetch') {
|
|
39
|
+
return fetchMessages(messages);
|
|
40
|
+
} else {
|
|
41
|
+
throw new Error('Invalid action. Use "message", "private", or "fetch"');
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Send a new message
|
|
47
|
+
*/
|
|
48
|
+
function sendMessage(params, messages, privateChats, sessions, u, now) {
|
|
49
|
+
const { message, session, token } = params;
|
|
50
|
+
|
|
51
|
+
// Input validation for message action
|
|
52
|
+
if (!message) throw new Error('Please provide a message');
|
|
53
|
+
if (!session) throw new Error('Please provide a valid session ID');
|
|
54
|
+
|
|
55
|
+
// Session validation
|
|
56
|
+
if (sessions[u] && sessions[u].user !== session) {
|
|
57
|
+
throw new Error('Session ID mismatch');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Create message object
|
|
61
|
+
const msg = {
|
|
62
|
+
username: params.username,
|
|
63
|
+
message,
|
|
64
|
+
timestamp: params.timestamp || new Date().toISOString()
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// Store message based on whether it's private or public
|
|
68
|
+
if (token) {
|
|
69
|
+
privateChats[token] = privateChats[token] || [];
|
|
70
|
+
privateChats[token].push(msg);
|
|
71
|
+
setTimeout(() => { delete privateChats[token]; }, 3600000);
|
|
72
|
+
} else {
|
|
73
|
+
messages.push(msg);
|
|
74
|
+
setTimeout(() => messages.splice(messages.indexOf(msg), 1), 3600000);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Update session
|
|
78
|
+
sessions[u] = sessions[u] || { user: session, last: now };
|
|
79
|
+
sessions[u].last = now;
|
|
80
|
+
|
|
81
|
+
setTimeout(() => {
|
|
82
|
+
if (now - sessions[u].last >= 3600000) delete sessions[u];
|
|
83
|
+
}, 3600000);
|
|
84
|
+
|
|
85
|
+
return { message: 'Message sent successfully' };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Get private chat messages
|
|
90
|
+
*/
|
|
91
|
+
function getPrivateChat(params, privateChats) {
|
|
92
|
+
const { token } = params;
|
|
93
|
+
|
|
94
|
+
// Input validation for private action
|
|
95
|
+
if (!token) throw new Error('Please provide a valid token');
|
|
96
|
+
|
|
97
|
+
// Return messages if token exists
|
|
98
|
+
if (privateChats[token]) return privateChats[token];
|
|
99
|
+
|
|
100
|
+
throw new Error('Invalid or expired token.');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Fetch all public messages
|
|
105
|
+
*/
|
|
106
|
+
function fetchMessages(messages) {
|
|
107
|
+
if (messages.length > 0) return messages;
|
|
108
|
+
throw new Error('No messages stored.');
|
|
109
109
|
}
|
package/modules/v3/color.js
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generate a random color in multiple formats
|
|
3
|
-
*
|
|
4
|
-
* @returns {Object} Color in various formats (hex, rgb, hsl, hsv, hwb, cmyk)
|
|
5
|
-
*/
|
|
6
|
-
export default function color() {
|
|
7
|
-
const r = Math.floor(Math.random() * 256), g = Math.floor(Math.random() * 256), b = Math.floor(Math.random() * 256);
|
|
8
|
-
|
|
9
|
-
const hsl = (() => {
|
|
10
|
-
const r1 = r / 255, g1 = g / 255, b1 = b / 255, max = Math.max(r1, g1, b1), min = Math.min(r1, g1, b1), l = (max + min) / 2;
|
|
11
|
-
if (max === min) return [0, 0, l * 100];
|
|
12
|
-
const d = max - min, s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
13
|
-
let h = { [r1]: (g1 - b1) / d + (g1 < b1 ? 6 : 0), [g1]: (b1 - r1) / d + 2, [b1]: (r1 - g1) / d + 4 }[max];
|
|
14
|
-
return [h * 60 % 360, s * 100, l * 100];
|
|
15
|
-
})();
|
|
16
|
-
|
|
17
|
-
const hsv = (() => {
|
|
18
|
-
const max = Math.max(r, g, b), min = Math.min(r, g, b), v = max / 255, s = max ? (max - min) / max : 0;
|
|
19
|
-
let h = max === min ? 0 : { [r]: (g - b) / (max - min), [g]: 2 + (b - r) / (max - min), [b]: 4 + (r - g) / (max - min) }[max];
|
|
20
|
-
return [h * 60 % 360, s * 100, v * 100];
|
|
21
|
-
})();
|
|
22
|
-
|
|
23
|
-
const hwb = (() => {
|
|
24
|
-
const [h] = hsv, whiteness = Math.min(r, g, b) / 255, blackness = 1 - Math.max(r, g, b) / 255;
|
|
25
|
-
return [h, whiteness * 100, blackness * 100];
|
|
26
|
-
})();
|
|
27
|
-
|
|
28
|
-
const cmyk = (() => {
|
|
29
|
-
const k = 1 - Math.max(r, g, b) / 255, c = (1 - r / 255 - k) / (1 - k) || 0, m = (1 - g / 255 - k) / (1 - k) || 0, y = (1 - b / 255 - k) / (1 - k) || 0;
|
|
30
|
-
return [c, m, y, k].map(x => x * 100);
|
|
31
|
-
})();
|
|
32
|
-
|
|
33
|
-
return {
|
|
34
|
-
hex: `#${[r, g, b].map(x => x.toString(16).padStart(2, '0')).join('')}`,
|
|
35
|
-
rgb: `rgb(${r}, ${g}, ${b})`,
|
|
36
|
-
hsl: `hsl(${hsl[0].toFixed(1)}, ${hsl[1].toFixed(1)}%, ${hsl[2].toFixed(1)}%)`,
|
|
37
|
-
hsv: `hsv(${hsv[0].toFixed(1)}, ${hsv[1].toFixed(1)}%, ${hsv[2].toFixed(1)}%)`,
|
|
38
|
-
hwb: `hwb(${hwb[0].toFixed(1)}, ${hwb[1].toFixed(1)}%, ${hwb[2].toFixed(1)}%)`,
|
|
39
|
-
cmyk: `cmyk(${cmyk.map(x => x.toFixed(1)).join('%, ')}%)`
|
|
40
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* Generate a random color in multiple formats
|
|
3
|
+
*
|
|
4
|
+
* @returns {Object} Color in various formats (hex, rgb, hsl, hsv, hwb, cmyk)
|
|
5
|
+
*/
|
|
6
|
+
export default function color() {
|
|
7
|
+
const r = Math.floor(Math.random() * 256), g = Math.floor(Math.random() * 256), b = Math.floor(Math.random() * 256);
|
|
8
|
+
|
|
9
|
+
const hsl = (() => {
|
|
10
|
+
const r1 = r / 255, g1 = g / 255, b1 = b / 255, max = Math.max(r1, g1, b1), min = Math.min(r1, g1, b1), l = (max + min) / 2;
|
|
11
|
+
if (max === min) return [0, 0, l * 100];
|
|
12
|
+
const d = max - min, s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
13
|
+
let h = { [r1]: (g1 - b1) / d + (g1 < b1 ? 6 : 0), [g1]: (b1 - r1) / d + 2, [b1]: (r1 - g1) / d + 4 }[max];
|
|
14
|
+
return [h * 60 % 360, s * 100, l * 100];
|
|
15
|
+
})();
|
|
16
|
+
|
|
17
|
+
const hsv = (() => {
|
|
18
|
+
const max = Math.max(r, g, b), min = Math.min(r, g, b), v = max / 255, s = max ? (max - min) / max : 0;
|
|
19
|
+
let h = max === min ? 0 : { [r]: (g - b) / (max - min), [g]: 2 + (b - r) / (max - min), [b]: 4 + (r - g) / (max - min) }[max];
|
|
20
|
+
return [h * 60 % 360, s * 100, v * 100];
|
|
21
|
+
})();
|
|
22
|
+
|
|
23
|
+
const hwb = (() => {
|
|
24
|
+
const [h] = hsv, whiteness = Math.min(r, g, b) / 255, blackness = 1 - Math.max(r, g, b) / 255;
|
|
25
|
+
return [h, whiteness * 100, blackness * 100];
|
|
26
|
+
})();
|
|
27
|
+
|
|
28
|
+
const cmyk = (() => {
|
|
29
|
+
const k = 1 - Math.max(r, g, b) / 255, c = (1 - r / 255 - k) / (1 - k) || 0, m = (1 - g / 255 - k) / (1 - k) || 0, y = (1 - b / 255 - k) / (1 - k) || 0;
|
|
30
|
+
return [c, m, y, k].map(x => x * 100);
|
|
31
|
+
})();
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
hex: `#${[r, g, b].map(x => x.toString(16).padStart(2, '0')).join('')}`,
|
|
35
|
+
rgb: `rgb(${r}, ${g}, ${b})`,
|
|
36
|
+
hsl: `hsl(${hsl[0].toFixed(1)}, ${hsl[1].toFixed(1)}%, ${hsl[2].toFixed(1)}%)`,
|
|
37
|
+
hsv: `hsv(${hsv[0].toFixed(1)}, ${hsv[1].toFixed(1)}%, ${hsv[2].toFixed(1)}%)`,
|
|
38
|
+
hwb: `hwb(${hwb[0].toFixed(1)}, ${hwb[1].toFixed(1)}%, ${hwb[2].toFixed(1)}%)`,
|
|
39
|
+
cmyk: `cmyk(${cmyk.map(x => x.toFixed(1)).join('%, ')}%)`
|
|
40
|
+
};
|
|
41
41
|
}
|
package/modules/v3/convert.js
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Converts values between different temperature units
|
|
3
|
-
*
|
|
4
|
-
* @param {number|string} value - The value to convert
|
|
5
|
-
* @param {string} from - The source unit (celsius, fahrenheit, or kelvin)
|
|
6
|
-
* @param {string} to - The target unit (celsius, fahrenheit, or kelvin)
|
|
7
|
-
* @returns {Object} - Object containing the conversion details
|
|
8
|
-
* @throws {Error} - If conversion parameters are invalid
|
|
9
|
-
*/
|
|
10
|
-
export default function convert(value, from, to) {
|
|
11
|
-
const conversions = {
|
|
12
|
-
celsius: {
|
|
13
|
-
fahrenheit: (val) => (val * 9) / 5 + 32,
|
|
14
|
-
kelvin: (val) => val + 273.15
|
|
15
|
-
},
|
|
16
|
-
fahrenheit: {
|
|
17
|
-
celsius: (val) => ((val - 32) * 5) / 9,
|
|
18
|
-
kelvin: (val) => ((val - 32) * 5) / 9 + 273.15
|
|
19
|
-
},
|
|
20
|
-
kelvin: {
|
|
21
|
-
celsius: (val) => val - 273.15,
|
|
22
|
-
fahrenheit: (val) => ((val - 273.15) * 9) / 5 + 32
|
|
23
|
-
},
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const convert = conversions[from.toLowerCase()]?.[to.toLowerCase()];
|
|
27
|
-
|
|
28
|
-
if (!convert) throw new Error('Invalid conversion unit');
|
|
29
|
-
if (isNaN(value)) throw new Error('Value must be a number');
|
|
30
|
-
if (value < -273.15) throw new Error('Value must be greater than absolute zero');
|
|
31
|
-
if (value > 1e6) throw new Error('Value must be less than 1,000,000');
|
|
32
|
-
|
|
33
|
-
return {
|
|
34
|
-
from,
|
|
35
|
-
to,
|
|
36
|
-
value: parseFloat(value),
|
|
37
|
-
result: convert(parseFloat(value))
|
|
38
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* Converts values between different temperature units
|
|
3
|
+
*
|
|
4
|
+
* @param {number|string} value - The value to convert
|
|
5
|
+
* @param {string} from - The source unit (celsius, fahrenheit, or kelvin)
|
|
6
|
+
* @param {string} to - The target unit (celsius, fahrenheit, or kelvin)
|
|
7
|
+
* @returns {Object} - Object containing the conversion details
|
|
8
|
+
* @throws {Error} - If conversion parameters are invalid
|
|
9
|
+
*/
|
|
10
|
+
export default function convert(value, from, to) {
|
|
11
|
+
const conversions = {
|
|
12
|
+
celsius: {
|
|
13
|
+
fahrenheit: (val) => (val * 9) / 5 + 32,
|
|
14
|
+
kelvin: (val) => val + 273.15
|
|
15
|
+
},
|
|
16
|
+
fahrenheit: {
|
|
17
|
+
celsius: (val) => ((val - 32) * 5) / 9,
|
|
18
|
+
kelvin: (val) => ((val - 32) * 5) / 9 + 273.15
|
|
19
|
+
},
|
|
20
|
+
kelvin: {
|
|
21
|
+
celsius: (val) => val - 273.15,
|
|
22
|
+
fahrenheit: (val) => ((val - 273.15) * 9) / 5 + 32
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const convert = conversions[from.toLowerCase()]?.[to.toLowerCase()];
|
|
27
|
+
|
|
28
|
+
if (!convert) throw new Error('Invalid conversion unit');
|
|
29
|
+
if (isNaN(value)) throw new Error('Value must be a number');
|
|
30
|
+
if (value < -273.15) throw new Error('Value must be greater than absolute zero');
|
|
31
|
+
if (value > 1e6) throw new Error('Value must be less than 1,000,000');
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
from,
|
|
35
|
+
to,
|
|
36
|
+
value: parseFloat(value),
|
|
37
|
+
result: convert(parseFloat(value))
|
|
38
|
+
};
|
|
39
39
|
}
|
package/modules/v3/domain.js
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
import { random, genIP } from './utils.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Generate random domain information
|
|
5
|
-
*
|
|
6
|
-
* @returns {Object} Domain details including DNS, hosting, and SEO metrics
|
|
7
|
-
*/
|
|
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'];
|
|
12
|
-
|
|
13
|
-
const domain = `${random(domains)}${random(tlds)}`;
|
|
14
|
-
const fulldomain = `${random(subdomains)}${domain}`;
|
|
15
|
-
|
|
16
|
-
const ips = Array.from({ length: Math.floor(Math.random() * 3) + 1 }, genIP);
|
|
17
|
-
const dns = Array.from({ length: Math.floor(Math.random() * 5) + 1 }, genIP);
|
|
18
|
-
|
|
19
|
-
return {
|
|
20
|
-
domain,
|
|
21
|
-
full_domain: fulldomain,
|
|
22
|
-
ip_address: ips,
|
|
23
|
-
ssl_certified: Math.random() > 0.5,
|
|
24
|
-
hosting_provider: random(['AWS', 'Bluehost', 'DigitalOcean', 'GitHub', 'HostGator', 'Render', 'SiteGround']),
|
|
25
|
-
dns_servers: dns,
|
|
26
|
-
dns_provider: random(['AWS Route 53', 'Cloudflare', 'GoDaddy', 'Google DNS', 'Namecheap']),
|
|
27
|
-
traffic: `${Math.floor(Math.random() * 10000)} visits/day`,
|
|
28
|
-
seo_score: Math.floor(Math.random() * 100),
|
|
29
|
-
page_rank: Math.floor(Math.random() * 10),
|
|
30
|
-
country: random(['Australia', 'Canada', 'France', 'Germany', 'India', 'Japan', 'UK', 'USA']),
|
|
31
|
-
website_type: random(['Blog', 'Community', 'Corporate', 'Educational', 'E-commerce', 'Personal', 'Portfolio']),
|
|
32
|
-
random_name: domain.split('.')[0],
|
|
33
|
-
random_subdomain: fulldomain.split('.')[0],
|
|
34
|
-
random_tld: domain.split('.').pop(),
|
|
35
|
-
backlinks_count: Math.floor(Math.random() * 1000),
|
|
36
|
-
creation_date: new Date(Date.now() - Math.floor(Math.random() * 10000000000)).toISOString(),
|
|
37
|
-
expiration_date: new Date(Date.now() + Math.floor(Math.random() * 10000000000)).toISOString(),
|
|
38
|
-
};
|
|
1
|
+
import { random, genIP } from './utils.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generate random domain information
|
|
5
|
+
*
|
|
6
|
+
* @returns {Object} Domain details including DNS, hosting, and SEO metrics
|
|
7
|
+
*/
|
|
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'];
|
|
12
|
+
|
|
13
|
+
const domain = `${random(domains)}${random(tlds)}`;
|
|
14
|
+
const fulldomain = `${random(subdomains)}${domain}`;
|
|
15
|
+
|
|
16
|
+
const ips = Array.from({ length: Math.floor(Math.random() * 3) + 1 }, genIP);
|
|
17
|
+
const dns = Array.from({ length: Math.floor(Math.random() * 5) + 1 }, genIP);
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
domain,
|
|
21
|
+
full_domain: fulldomain,
|
|
22
|
+
ip_address: ips,
|
|
23
|
+
ssl_certified: Math.random() > 0.5,
|
|
24
|
+
hosting_provider: random(['AWS', 'Bluehost', 'DigitalOcean', 'GitHub', 'HostGator', 'Render', 'SiteGround']),
|
|
25
|
+
dns_servers: dns,
|
|
26
|
+
dns_provider: random(['AWS Route 53', 'Cloudflare', 'GoDaddy', 'Google DNS', 'Namecheap']),
|
|
27
|
+
traffic: `${Math.floor(Math.random() * 10000)} visits/day`,
|
|
28
|
+
seo_score: Math.floor(Math.random() * 100),
|
|
29
|
+
page_rank: Math.floor(Math.random() * 10),
|
|
30
|
+
country: random(['Australia', 'Canada', 'France', 'Germany', 'India', 'Japan', 'UK', 'USA']),
|
|
31
|
+
website_type: random(['Blog', 'Community', 'Corporate', 'Educational', 'E-commerce', 'Personal', 'Portfolio']),
|
|
32
|
+
random_name: domain.split('.')[0],
|
|
33
|
+
random_subdomain: fulldomain.split('.')[0],
|
|
34
|
+
random_tld: domain.split('.').pop(),
|
|
35
|
+
backlinks_count: Math.floor(Math.random() * 1000),
|
|
36
|
+
creation_date: new Date(Date.now() - Math.floor(Math.random() * 10000000000)).toISOString(),
|
|
37
|
+
expiration_date: new Date(Date.now() + Math.floor(Math.random() * 10000000000)).toISOString(),
|
|
38
|
+
};
|
|
39
39
|
}
|
package/modules/v3/hash.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { getHashes, createHash } from 'crypto';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Generate a hash of text using the specified algorithm
|
|
5
|
-
*
|
|
6
|
-
* @param {string} text - The text to hash
|
|
7
|
-
* @param {string} method - The hash algorithm to use
|
|
8
|
-
* @returns {Object} Object containing the method and resulting hash
|
|
9
|
-
*/
|
|
10
|
-
export default function hash(text, method) {
|
|
11
|
-
const methods = getHashes();
|
|
12
|
-
if (!methods.includes(method)) return { error: `Unsupported method. Use one of: ${methods.join(', ')}` };
|
|
13
|
-
|
|
14
|
-
const hash = createHash(method).update(text).digest('hex');
|
|
15
|
-
return { method, hash };
|
|
1
|
+
import { getHashes, createHash } from 'crypto';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generate a hash of text using the specified algorithm
|
|
5
|
+
*
|
|
6
|
+
* @param {string} text - The text to hash
|
|
7
|
+
* @param {string} method - The hash algorithm to use
|
|
8
|
+
* @returns {Object} Object containing the method and resulting hash
|
|
9
|
+
*/
|
|
10
|
+
export default function hash(text, method) {
|
|
11
|
+
const methods = getHashes();
|
|
12
|
+
if (!methods.includes(method)) return { error: `Unsupported method. Use one of: ${methods.join(', ')}` };
|
|
13
|
+
|
|
14
|
+
const hash = createHash(method).update(text).digest('hex');
|
|
15
|
+
return { method, hash };
|
|
16
16
|
}
|
|
@@ -1,51 +1,55 @@
|
|
|
1
|
-
import { formatDate } from './utils.js';
|
|
2
|
-
import ical from 'ical.js';
|
|
3
|
-
import fetch from 'node-fetch';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Parse an ICS calendar file and extract event information
|
|
7
|
-
*
|
|
8
|
-
* @param {string} url - URL to the ICS file
|
|
9
|
-
* @param {string} [detail] - Detail level of returned information ('full', 'list', or undefined)
|
|
10
|
-
* @returns {Promise<Array>} Array of calendar events
|
|
11
|
-
* @throws {Error} If the ICS file is invalid or inaccessible
|
|
12
|
-
*/
|
|
13
|
-
export default async function hyperplanning(url, detail) {
|
|
14
|
-
const response = await fetch(url);
|
|
15
|
-
|
|
16
|
-
if (!response.ok || !(response.headers.get('content-type') || '').includes('text/calendar')) {
|
|
17
|
-
throw new Error('Invalid ICS file format.');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const events = new ical.Component(ical.parse(await response.text()))
|
|
21
|
-
.getAllSubcomponents('vevent')
|
|
22
|
-
.map(e => {
|
|
23
|
-
const evt = new ical.Event(e);
|
|
24
|
-
const summary = evt.summary.split(' ').filter(part => part !== '-');
|
|
25
|
-
const start = formatDate(evt.startDate.toJSDate());
|
|
26
|
-
const end = formatDate(evt.endDate.toJSDate());
|
|
27
|
-
|
|
28
|
-
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();
|
|
31
|
-
|
|
32
|
-
return {
|
|
33
|
-
summary,
|
|
34
|
-
subject: extract('Matière :'),
|
|
35
|
-
teacher: extract('Enseignant :'),
|
|
36
|
-
classes: extract('Promotions :').split(', ').map(c => c.trim()),
|
|
37
|
-
type: extract('Salle :') || undefined,
|
|
38
|
-
start,
|
|
39
|
-
end
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (detail === 'list') return { summary, start, end };
|
|
44
|
-
|
|
45
|
-
return {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
1
|
+
import { formatDate } from './utils.js';
|
|
2
|
+
import ical from 'ical.js';
|
|
3
|
+
import fetch from 'node-fetch';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Parse an ICS calendar file and extract event information
|
|
7
|
+
*
|
|
8
|
+
* @param {string} url - URL to the ICS file
|
|
9
|
+
* @param {string} [detail] - Detail level of returned information ('full', 'list', or undefined)
|
|
10
|
+
* @returns {Promise<Array>} Array of calendar events
|
|
11
|
+
* @throws {Error} If the ICS file is invalid or inaccessible
|
|
12
|
+
*/
|
|
13
|
+
export default async function hyperplanning(url, detail) {
|
|
14
|
+
const response = await fetch(url);
|
|
15
|
+
|
|
16
|
+
if (!response.ok || !(response.headers.get('content-type') || '').includes('text/calendar')) {
|
|
17
|
+
throw new Error('Invalid ICS file format.');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const events = new ical.Component(ical.parse(await response.text()))
|
|
21
|
+
.getAllSubcomponents('vevent')
|
|
22
|
+
.map(e => {
|
|
23
|
+
const evt = new ical.Event(e);
|
|
24
|
+
const summary = (evt.summary || '').split(' ').filter(part => part !== '-');
|
|
25
|
+
const start = formatDate(evt.startDate.toJSDate());
|
|
26
|
+
const end = formatDate(evt.endDate.toJSDate());
|
|
27
|
+
|
|
28
|
+
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();
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
summary,
|
|
34
|
+
subject: extract('Matière :'),
|
|
35
|
+
teacher: extract('Enseignant :'),
|
|
36
|
+
classes: extract('Promotions :').split(', ').map(c => c.trim()),
|
|
37
|
+
type: extract('Salle :') || undefined,
|
|
38
|
+
start,
|
|
39
|
+
end
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (detail === 'list') return { summary, start, end };
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
summary: evt.summary || '',
|
|
47
|
+
start,
|
|
48
|
+
end
|
|
49
|
+
};
|
|
50
|
+
})
|
|
51
|
+
.sort((a, b) => new Date(a.start) - new Date(b.start))
|
|
52
|
+
.filter(e => new Date(e.end) >= new Date());
|
|
53
|
+
|
|
54
|
+
return events;
|
|
51
55
|
}
|