diff --git a/discord/index.js b/discord/index.js index 0c8edae..9e9dec6 100644 --- a/discord/index.js +++ b/discord/index.js @@ -11,6 +11,19 @@ const { const axios = require("axios"); const ping = require("ping"); const whois = require('whois-json'); +const fs = require('fs'); +const path = require('path'); + +const tempDir = path.join(__dirname, '../temp'); +if (fs.existsSync(tempDir)) { + console.log("Cleaning up temp directory..."); + const files = fs.readdirSync(tempDir); + for (const file of files) { + fs.unlinkSync(path.join(tempDir, file)); + } +} else { + fs.mkdirSync(tempDir, { recursive: true }); +} const client = new Client({ intents: [ @@ -256,7 +269,117 @@ const globalCommands = [ required: true, } ] - } + }, + { + name: "wikipedia", + description: "Get a summary of a Wikipedia article", + type: ApplicationCommandType.ChatInput, + dm_permission: true, + options: [ + { + name: "query", + description: "The topic to search for on Wikipedia", + type: ApplicationCommandOptionType.String, + required: true, + }, + { + name: "language", + description: "Wikipedia language (default: en)", + type: ApplicationCommandOptionType.String, + required: false, + choices: [ + { name: "English", value: "en" }, + { name: "Spanish", value: "es" }, + { name: "French", value: "fr" }, + { name: "German", value: "de" }, + { name: "Russian", value: "ru" }, + { name: "Japanese", value: "ja" }, + { name: "Chinese", value: "zh" }, + { name: "Turkish", value: "tr" } + ] + } + ], + }, + { + name: "urban", + description: "Look up a term on Urban Dictionary", + type: ApplicationCommandType.ChatInput, + dm_permission: true, + options: [ + { + name: "term", + description: "The slang term to look up", + type: ApplicationCommandOptionType.String, + required: true, + }, + { + name: "random", + description: "Get a random definition instead", + type: ApplicationCommandOptionType.Boolean, + required: false + } + ], + }, + { + name: "currency", + description: "Convert between currencies using real-time exchange rates", + type: ApplicationCommandType.ChatInput, + dm_permission: true, + options: [ + { + name: "amount", + description: "Amount to convert", + type: ApplicationCommandOptionType.Number, + required: true, + }, + { + name: "from", + description: "Source currency code (e.g., USD)", + type: ApplicationCommandOptionType.String, + required: true, + }, + { + name: "to", + description: "Target currency code (e.g., EUR)", + type: ApplicationCommandOptionType.String, + required: true, + } + ], + }, + { + name: "hash", + description: "Generate hash of text or file (up to 500MB)", + type: ApplicationCommandType.ChatInput, + dm_permission: true, + options: [ + { + name: "algorithm", + description: "Hash algorithm to use", + type: ApplicationCommandOptionType.String, + required: true, + choices: [ + { name: "MD5", value: "md5" }, + { name: "SHA-1", value: "sha1" }, + { name: "SHA-256", value: "sha256" }, + { name: "SHA-512", value: "sha512" }, + { name: "SHA3-256", value: "sha3-256" }, + { name: "SHA3-512", value: "sha3-512" } + ] + }, + { + name: "text", + description: "Text to hash (if not uploading a file)", + type: ApplicationCommandOptionType.String, + required: false, + }, + { + name: "file", + description: "File to hash (up to 500MB)", + type: ApplicationCommandOptionType.Attachment, + required: false, + } + ], + } ]; // Commands that only make sense in a guild context @@ -950,7 +1073,98 @@ client.on("interactionCreate", async (interaction) => { ephemeral: true }); } - break; + break; + + case "wikipedia": + try { + await interaction.deferReply(); + const query = interaction.options.getString("query"); + const language = interaction.options.getString("language") || "en"; + + // Import the wikipedia package + const wikipedia = require('wikipedia'); + + // Set the language + wikipedia.setLang(language); + + // Search for the query + const searchResults = await wikipedia.search(query); + + if (!searchResults.results || searchResults.results.length === 0) { + await interaction.editReply({ + content: `No results found for "${query}" on Wikipedia.`, + ephemeral: true + }); + return; + } + + // Get the first result + const page = await wikipedia.page(searchResults.results[0].title); + + // Get summary and basic info + const summary = await page.summary(); + + // Create a rich embed + const wikiEmbed = { + title: summary.title, + url: summary.content_urls.desktop.page, + description: summary.extract.length > 1000 + ? summary.extract.substring(0, 1000) + "..." + : summary.extract, + color: 0x0099ff, + thumbnail: summary.thumbnail + ? { url: summary.thumbnail.source } + : null, + fields: [ + { + name: "Page ID", + value: summary.pageid.toString(), + inline: true + }, + { + name: "Language", + value: language.toUpperCase(), + inline: true + } + ], + footer: { + text: "Powered by Wikipedia", + icon_url: "https://upload.wikimedia.org/wikipedia/commons/thumb/8/80/Wikipedia-logo-v2.svg/103px-Wikipedia-logo-v2.svg.png" + }, + timestamp: new Date() + }; + + // Add a related articles field if we have other search results + if (searchResults.results.length > 1) { + const relatedArticles = searchResults.results + .slice(1, 4) // Get 3 related articles + .map(result => `[${result.title}](https://${language}.wikipedia.org/wiki/${encodeURIComponent(result.title.replace(/ /g, '_'))})`) + .join('\n'); + + wikiEmbed.fields.push({ + name: "Related Articles", + value: relatedArticles + }); + } + + await interaction.editReply({ embeds: [wikiEmbed] }); + } catch (error) { + console.error(error); + + // Handle specific Wikipedia errors + if (error.message.includes("No article found")) { + await interaction.editReply({ + content: "Couldn't find a specific Wikipedia article with that title. Try a different search term.", + ephemeral: true + }); + } else { + await interaction.editReply({ + content: "Error fetching Wikipedia data. Please try again later.", + ephemeral: true + }); + } + } + break; case "whois": try { @@ -1113,9 +1327,384 @@ client.on("interactionCreate", async (interaction) => { ephemeral: true }); } - break; - - default: + break; + + case "urban": + try { + await interaction.deferReply(); + const term = interaction.options.getString("term"); + const isRandom = interaction.options.getBoolean("random") || false; + + // API endpoint + const endpoint = isRandom + ? "https://api.urbandictionary.com/v0/random" + : `https://api.urbandictionary.com/v0/define?term=${encodeURIComponent(term)}`; + + const response = await axios.get(endpoint); + + if (!response.data.list || response.data.list.length === 0) { + await interaction.editReply({ + content: `No definitions found for "${term}" on Urban Dictionary.`, + ephemeral: true + }); + return; + } + + // Sort by thumbs up count if there are multiple definitions + const definitions = response.data.list.sort((a, b) => b.thumbs_up - a.thumbs_up); + const definition = definitions[0]; + + // Clean up the text by replacing square brackets with formatted links + let cleanDefinition = definition.definition.replace(/\[([^\]]+)\]/g, '**$1**'); + let cleanExample = definition.example.replace(/\[([^\]]+)\]/g, '**$1**'); + + // Truncate if too long + if (cleanDefinition.length > 1024) { + cleanDefinition = cleanDefinition.substring(0, 1021) + '...'; + } + + if (cleanExample.length > 1024) { + cleanExample = cleanExample.substring(0, 1021) + '...'; + } + + // Create a rich embed + const urbanEmbed = { + title: isRandom ? definition.word : term, + url: definition.permalink, + color: 0xEFFF00, // Urban Dictionary yellow + fields: [ + { + name: "Definition", + value: cleanDefinition || "No definition provided" + } + ], + footer: { + text: `👍 ${definition.thumbs_up} | 👎 ${definition.thumbs_down} | Written by ${definition.author}`, + icon_url: "https://i.imgur.com/VFXr0ID.jpg" + }, + timestamp: new Date(definition.written_on) + }; + + // Add example if it exists + if (cleanExample && cleanExample.trim().length > 0) { + urbanEmbed.fields.push({ + name: "Example", + value: cleanExample + }); + } + + // Add related definitions if there are more + if (definitions.length > 1) { + const relatedCount = Math.min(definitions.length - 1, 3); + urbanEmbed.fields.push({ + name: `${relatedCount} More Definition${relatedCount > 1 ? 's' : ''}`, + value: `This term has ${definitions.length} definitions. Use the link above to see them all.` + }); + } + + // Add a warning that content might be offensive + const warningMessage = "⚠️ **Note:** Urban Dictionary contains user-submitted content that may be offensive or inappropriate."; + + await interaction.editReply({ + content: warningMessage, + embeds: [urbanEmbed] + }); + } catch (error) { + console.error(error); + await interaction.editReply({ + content: "Error fetching Urban Dictionary definition. Please try again later.", + ephemeral: true + }); + } + break; + case "currency": + try { + await interaction.deferReply(); + const amount = interaction.options.getNumber("amount"); + const fromCurrency = interaction.options.getString("from").toUpperCase(); + const toCurrency = interaction.options.getString("to").toUpperCase(); + + // Check if API key is configured + if (!process.env.EXCHANGE_RATE_API_KEY) { + await interaction.editReply({ + content: "Exchange Rate API key not configured. Please add EXCHANGE_RATE_API_KEY to your environment variables.", + ephemeral: true + }); + return; + } + + // Validate amount + if (amount <= 0) { + await interaction.editReply({ + content: "Please provide a positive amount to convert.", + ephemeral: true + }); + return; + } + + // Fetch exchange rates + const apiUrl = `https://v6.exchangerate-api.com/v6/${process.env.EXCHANGE_RATE_API_KEY}/latest/${fromCurrency}`; + const response = await axios.get(apiUrl); + + // Check if the source currency is valid + if (response.data.result === "error") { + await interaction.editReply({ + content: `Error: ${response.data.error-type || "Invalid request"}. Please check your currency codes.`, + ephemeral: true + }); + return; + } + + // Check if target currency exists in the response + if (!response.data.conversion_rates[toCurrency]) { + await interaction.editReply({ + content: `Could not find exchange rate for ${toCurrency}. Please check your currency code.`, + ephemeral: true + }); + return; + } + + // Calculate the converted amount + const rate = response.data.conversion_rates[toCurrency]; + const convertedAmount = amount * rate; + + // Format numbers with proper separators and decimals + const formatNumber = (num) => { + return new Intl.NumberFormat('en-US', { + minimumFractionDigits: 2, + maximumFractionDigits: 4 + }).format(num); + }; + + // Get currency information to display symbols + const currencyInfo = { + USD: { symbol: '$', name: 'US Dollar' }, + EUR: { symbol: '€', name: 'Euro' }, + GBP: { symbol: '£', name: 'British Pound' }, + JPY: { symbol: '¥', name: 'Japanese Yen' }, + TRY: { symbol: '₺', name: 'Turkish Lira' }, + // Add more currencies as needed + }; + + const fromCurrencyInfo = currencyInfo[fromCurrency] || { symbol: '', name: fromCurrency }; + const toCurrencyInfo = currencyInfo[toCurrency] || { symbol: '', name: toCurrency }; + + // Create a rich embed + const conversionEmbed = { + title: "Currency Conversion", + color: 0x4CAF50, // Green + fields: [ + { + name: "From", + value: `${fromCurrencyInfo.symbol} ${formatNumber(amount)} ${fromCurrency} (${fromCurrencyInfo.name})`, + inline: false + }, + { + name: "To", + value: `${toCurrencyInfo.symbol} ${formatNumber(convertedAmount)} ${toCurrency} (${toCurrencyInfo.name})`, + inline: false + }, + { + name: "Exchange Rate", + value: `1 ${fromCurrency} = ${formatNumber(rate)} ${toCurrency}`, + inline: true + }, + { + name: "Last Updated", + value: new Date(response.data.time_last_update_unix * 1000).toLocaleString(), + inline: true + } + ], + footer: { + text: "Powered by ExchangeRate-API" + }, + timestamp: new Date() + }; + + await interaction.editReply({ embeds: [conversionEmbed] }); + } catch (error) { + console.error(error); + const errorMessage = error.response?.data?.error || "Error fetching exchange rates. Please try again later."; + await interaction.editReply({ + content: errorMessage, + ephemeral: true + }); + } + break; + case "hash": + try { + await interaction.deferReply(); + const algorithm = interaction.options.getString("algorithm"); + const text = interaction.options.getString("text"); + const file = interaction.options.getAttachment("file"); + + // Validate that either text or file is provided + if (!text && !file) { + await interaction.editReply({ + content: "Please provide either text or a file to hash.", + ephemeral: true + }); + return; + } + + // If both are provided, prioritize the file + if (text && file) { + await interaction.followUp({ + content: "Both text and file were provided. Processing the file and ignoring the text.", + ephemeral: true + }); + } + + // For text input, generate hash directly + if (text && !file) { + const crypto = require('crypto'); + const hash = crypto.createHash(algorithm).update(text).digest('hex'); + + const hashEmbed = { + title: `${algorithm.toUpperCase()} Hash`, + description: "Text hash generated successfully", + color: 0x3498db, + fields: [ + { + name: "Input Text", + value: text.length > 1024 ? text.substring(0, 1021) + "..." : text + }, + { + name: "Hash", + value: "```\n" + hash + "\n```" + } + ], + timestamp: new Date(), + footer: { text: `Algorithm: ${algorithm.toUpperCase()}` } + }; + + await interaction.editReply({ embeds: [hashEmbed] }); + return; + } + + // For file input, download and hash the file + if (file) { + // Check file size (500MB limit) + const maxSize = 500 * 1024 * 1024; // 500MB in bytes + if (file.size > maxSize) { + await interaction.editReply({ + content: `File is too large. Maximum size is 500MB. Your file is ${(file.size / (1024 * 1024)).toFixed(2)}MB.`, + ephemeral: true + }); + return; + } + + // If file is larger than 25MB, warn the user it might take a while + if (file.size > 25 * 1024 * 1024) { + await interaction.editReply({ + content: `Processing a ${(file.size / (1024 * 1024)).toFixed(2)}MB file. This might take a while...` + }); + } + + // Process the file using streams for efficiency + const fs = require('fs'); + const path = require('path'); + const crypto = require('crypto'); + const stream = require('stream'); + const { promisify } = require('util'); + const pipeline = promisify(stream.pipeline); + const axios = require('axios'); + + // Create a temporary file path + const tempDir = path.join(__dirname, '../temp'); + if (!fs.existsSync(tempDir)) { + fs.mkdirSync(tempDir, { recursive: true }); + } + + const tempFile = path.join(tempDir, `${Date.now()}_${file.name.replace(/[^a-zA-Z0-9.]/g, '_')}`); + + try { + // Download the file + const writer = fs.createWriteStream(tempFile); + const response = await axios({ + method: 'GET', + url: file.url, + responseType: 'stream' + }); + + await pipeline(response.data, writer); + + // After download completes, hash the file with progress updates + const fileSize = fs.statSync(tempFile).size; + const hash = crypto.createHash(algorithm); + const input = fs.createReadStream(tempFile); + + let processedBytes = 0; + let lastProgressUpdate = Date.now(); + + input.on('data', (chunk) => { + hash.update(chunk); + processedBytes += chunk.length; + + // Update progress every 3 seconds for files larger than 50MB + const now = Date.now(); + if (fileSize > 50 * 1024 * 1024 && now - lastProgressUpdate > 3000) { + const progress = (processedBytes / fileSize * 100).toFixed(2); + interaction.editReply({ + content: `Processing file: ${progress}% complete...` + }).catch(console.error); + lastProgressUpdate = now; + } + }); + + // Wait for the hash to complete + const hashHex = await new Promise((resolve, reject) => { + input.on('end', () => resolve(hash.digest('hex'))); + input.on('error', reject); + }); + + // Clean up the temp file + fs.unlinkSync(tempFile); + + // Create the response embed + const fileExtension = path.extname(file.name).toLowerCase(); + const hashEmbed = { + title: `${algorithm.toUpperCase()} Hash Generated`, + description: "File hash calculated successfully", + color: 0x00ff00, + fields: [ + { + name: "File", + value: `${file.name} (${(file.size / (1024 * 1024)).toFixed(2)} MB)` + }, + { + name: "Hash", + value: "```\n" + hashHex + "\n```" + } + ], + timestamp: new Date(), + footer: { text: `Algorithm: ${algorithm.toUpperCase()}` } + }; + + await interaction.editReply({ embeds: [hashEmbed] }); + } catch (fileError) { + console.error("File processing error:", fileError); + + // Clean up temp file if it exists + if (fs.existsSync(tempFile)) { + fs.unlinkSync(tempFile); + } + + await interaction.editReply({ + content: "Error processing file. The file might be inaccessible or corrupted.", + ephemeral: true + }); + } + } + } catch (error) { + console.error("Hash command error:", error); + await interaction.editReply({ + content: "Error generating hash. Please try again with a smaller file or different input.", + ephemeral: true + }); + } + break; + default: await interaction.reply({ content: `Command '${interaction.commandName}' not implemented yet.`, ephemeral: true diff --git a/package-lock.json b/package-lock.json index 670d18a..0bacc8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,14 +14,22 @@ "discord.js": "^14.18.0", "dotenv": "^16.4.7", "express": "^4.21.2", +<<<<<<< HEAD "ping": "^0.4.4", "whois-json": "^2.0.4" +======= + "nodejs": "^0.0.0", + "ping": "^0.4.4", + "whois-json": "^2.0.4", + "wikipedia": "^2.1.2" +>>>>>>> 8979cf12f0836cc64935d71ef45678c40ec8197e } }, "node_modules/@discordjs/builders": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.10.1.tgz", "integrity": "sha512-OWo1fY4ztL1/M/DUyRPShB4d/EzVfuUvPTRRHRIt/YxBrUYSz0a+JicD5F5zHFoNs2oTuWavxCOVFV1UljHTng==", + "license": "Apache-2.0", "dependencies": { "@discordjs/formatters": "^0.6.0", "@discordjs/util": "^1.1.1", @@ -42,6 +50,7 @@ "version": "1.5.3", "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz", "integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==", + "license": "Apache-2.0", "engines": { "node": ">=16.11.0" } @@ -50,6 +59,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.6.0.tgz", "integrity": "sha512-YIruKw4UILt/ivO4uISmrGq2GdMY6EkoTtD0oS0GvkJFRZbTSdPhzYiUILbJ/QslsvC9H9nTgGgnarnIl4jMfw==", + "license": "Apache-2.0", "dependencies": { "discord-api-types": "^0.37.114" }, @@ -64,6 +74,7 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.4.3.tgz", "integrity": "sha512-+SO4RKvWsM+y8uFHgYQrcTl/3+cY02uQOH7/7bKbVZsTfrfpoE62o5p+mmV+s7FVhTX82/kQUGGbu4YlV60RtA==", + "license": "Apache-2.0", "dependencies": { "@discordjs/collection": "^2.1.1", "@discordjs/util": "^1.1.1", @@ -86,6 +97,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.1.tgz", "integrity": "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==", + "license": "Apache-2.0", "engines": { "node": ">=18" }, @@ -97,6 +109,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.1.1.tgz", "integrity": "sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g==", + "license": "Apache-2.0", "engines": { "node": ">=18" }, @@ -108,6 +121,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.2.1.tgz", "integrity": "sha512-PBvenhZG56a6tMWF/f4P6f4GxZKJTBG95n7aiGSPTnodmz4N5g60t79rSIAq7ywMbv8A4jFtexMruH+oe51aQQ==", + "license": "Apache-2.0", "dependencies": { "@discordjs/collection": "^2.1.0", "@discordjs/rest": "^2.4.3", @@ -130,6 +144,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.1.tgz", "integrity": "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==", + "license": "Apache-2.0", "engines": { "node": ">=18" }, @@ -141,6 +156,7 @@ "version": "1.5.5", "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.5.tgz", "integrity": "sha512-cvGzxbba6sav2zZkH8GPf2oGk9yYoD5qrNWdu9fRehifgnFZJMV+nuy2nON2roRO4yQQ+v7MK/Pktl/HgfsUXg==", + "license": "MIT", "engines": { "node": ">=v14.0.0", "npm": ">=7.0.0" @@ -150,6 +166,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-4.0.0.tgz", "integrity": "sha512-d9dUmWVA7MMiKobL3VpLF8P2aeanRTu6ypG2OIaEv/ZHH/SUQ2iHOVyi5wAPjQ+HmnMuL0whK9ez8I/raWbtIg==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "lodash": "^4.17.21" @@ -162,6 +179,7 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.3.tgz", "integrity": "sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==", + "license": "MIT", "engines": { "node": ">=v14.0.0", "npm": ">=7.0.0" @@ -171,6 +189,7 @@ "version": "22.13.14", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.14.tgz", "integrity": "sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w==", + "license": "MIT", "dependencies": { "undici-types": "~6.20.0" } @@ -179,6 +198,7 @@ "version": "8.18.0", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.0.tgz", "integrity": "sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw==", + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -187,6 +207,7 @@ "version": "2.4.6", "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.4.6.tgz", "integrity": "sha512-RaI5qZo6D2CVS6sTHFKg1v5Ohq/+Bo2LZ5gzUEwZ/WkHhwtGTCB/sVLw8ijOkAUxasZ+WshN/Rzj4ywsABJ5ZA==", + "license": "MIT", "engines": { "node": ">=v14.0.0", "npm": ">=7.0.0" @@ -242,6 +263,7 @@ "version": "1.8.4", "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -496,12 +518,14 @@ "node_modules/discord-api-types": { "version": "0.37.119", "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.119.tgz", - "integrity": "sha512-WasbGFXEB+VQWXlo6IpW3oUv73Yuau1Ig4AZF/m13tXcTKnMpc/mHjpztIlz4+BM9FG9BHQkEXiPto3bKduQUg==" + "integrity": "sha512-WasbGFXEB+VQWXlo6IpW3oUv73Yuau1Ig4AZF/m13tXcTKnMpc/mHjpztIlz4+BM9FG9BHQkEXiPto3bKduQUg==", + "license": "MIT" }, "node_modules/discord.js": { "version": "14.18.0", "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.18.0.tgz", "integrity": "sha512-SvU5kVUvwunQhN2/+0t55QW/1EHfB1lp0TtLZUSXVHDmyHTrdOj5LRKdR0zLcybaA15F+NtdWuWmGOX9lE+CAw==", + "license": "Apache-2.0", "dependencies": { "@discordjs/builders": "^1.10.1", "@discordjs/collection": "1.5.3", @@ -536,6 +560,7 @@ "version": "16.4.7", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -677,7 +702,8 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" }, "node_modules/finalhandler": { "version": "1.3.1", @@ -899,6 +925,28 @@ "node": ">=0.10.0" } }, + "node_modules/infobox-parser": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/infobox-parser/-/infobox-parser-3.6.4.tgz", + "integrity": "sha512-d2lTlxKZX7WsYxk9/UPt51nkmZv5tbC75SSw4hfHqZ3LpRAn6ug0oru9xI2X+S78va3aUAze3xl/UqMuwLmJUw==", + "license": "MIT", + "dependencies": { + "camelcase": "^4.1.0" + }, + "funding": { + "type": "individual", + "url": "https://www.buymeacoffee.com/2tmRKi9" + } + }, + "node_modules/infobox-parser/node_modules/camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -973,12 +1021,14 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" }, "node_modules/lodash.snakecase": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", - "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==" + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "license": "MIT" }, "node_modules/lower-case": { "version": "1.1.4", @@ -998,7 +1048,8 @@ "node_modules/magic-bytes.js": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.10.0.tgz", - "integrity": "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==" + "integrity": "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==", + "license": "MIT" }, "node_modules/math-intrinsics": { "version": "1.1.0", @@ -1083,6 +1134,15 @@ "dependencies": { "lower-case": "^1.1.1" } +<<<<<<< HEAD +======= + }, + "node_modules/nodejs": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/nodejs/-/nodejs-0.0.0.tgz", + "integrity": "sha512-1V+0HwaB/dhxzidEFc4uJ3k52gLI4B6YBZgJIofjwYCSAkD6CI0me6TDBT2QM2nbGWNxCHcq9/wVynzQYZOhUg==", + "license": "ISC" +>>>>>>> 8979cf12f0836cc64935d71ef45678c40ec8197e }, "node_modules/object-assign": { "version": "4.1.1", @@ -1552,12 +1612,14 @@ "node_modules/ts-mixer": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz", - "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==" + "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==", + "license": "MIT" }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/type-is": { "version": "1.6.18", @@ -1581,6 +1643,7 @@ "version": "6.21.1", "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz", "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==", + "license": "MIT", "engines": { "node": ">=18.17" } @@ -1588,7 +1651,8 @@ "node_modules/undici-types": { "version": "6.20.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "license": "MIT" }, "node_modules/unpipe": { "version": "1.0.0", @@ -1662,6 +1726,19 @@ "whois": "^2.6.0" } }, + "node_modules/wikipedia": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/wikipedia/-/wikipedia-2.1.2.tgz", + "integrity": "sha512-RAYaMpXC9/E873RaSEtlEa8dXK4e0p5k98GKOd210MtkE5emm6fcnwD+N6ZA4cuffjDWagvhaQKtp/mGp2BOVQ==", + "license": "MIT", + "dependencies": { + "axios": "^1.4.0", + "infobox-parser": "^3.6.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -1680,6 +1757,7 @@ "version": "8.18.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, diff --git a/package.json b/package.json index 9a4ff83..27ed117 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,8 @@ "dotenv": "^16.4.7", "express": "^4.21.2", "nodejs": "^0.0.0", - "ping": "^0.4.4" + "ping": "^0.4.4", + "whois-json": "^2.0.4", + "wikipedia": "^2.1.2" } }